This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make undef use ck_fun and OA_SCALARREF
authorFather Chrysostomos <sprout@cpan.org>
Sat, 12 May 2012 21:25:44 +0000 (14:25 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 29 May 2012 16:36:25 +0000 (09:36 -0700)
In regen/opcodes, we have some operators that use ck_fun and have R
for the argument.  And there are some that use ck_lfun and have S for
the argument.

These both amount to more or less the same thing.

ck_fun/R goes through the OA_SCALARREF case in ck_fun, which calls
op_lvalue(scalar()) on the child op.

ck_lfun/S goes through the OA_SCALAR case in ck_fun, which calls
scalar(), and then ck_lfun sees to it that op_lvalue is called.

The only real difference is that the OA_SCALAR case makes sure there
are not too many arguments.

Since both core_prototype and pp_coreargs need special cases to deal
with OA_SCALAR that is really ‘supposed’ to be OA_SCALARREF, it
becomes simpler to add &CORE::undef if undef uses R.  In that case,
we also have to put the argument-checking in the OA_SCALARREF, but we
make it conditional on the op being an undef op, for the sake of doing
one thing at a time.  (This is a bit of a mess; see ticket #96006.)

op.c
opcode.h
regen/opcodes

diff --git a/op.c b/op.c
index 8bd45bf..c1424d0 100644 (file)
--- a/op.c
+++ b/op.c
@@ -8088,6 +8088,9 @@ Perl_ck_fun(pTHX_ OP *o)
                scalar(kid);
                break;
            case OA_SCALARREF:
+               if (type == OP_UNDEF && numargs == 1 && !(oa >> 4)
+                   && kid->op_type == OP_LIST)
+                   return too_many_arguments_pv(o,PL_op_desc[type], 0);
                op_lvalue(scalar(kid), type);
                break;
            }
@@ -10572,7 +10575,6 @@ Perl_core_prototype(pTHX_ SV *sv, const char *name, const int code,
     case KEY_pos:     retsetpvs(";\\[$*]", OP_POS);
     case KEY_splice:
        retsetpvs("+;$$@", OP_SPLICE);
-    case KEY_undef:   retsetpvs(";\\[$@%&*]", OP_UNDEF);
     case KEY___FILE__: case KEY___LINE__: case KEY___PACKAGE__:
        retsetpvs("", 0);
     case KEY_evalbytes:
@@ -10617,7 +10619,7 @@ Perl_core_prototype(pTHX_ SV *sv, const char *name, const int code,
            str[n++] = '$';
            str[n++] = '@';
            str[n++] = '%';
-           if (i == OP_LOCK) str[n++] = '&';
+           if (i == OP_LOCK || i == OP_UNDEF) str[n++] = '&';
            str[n++] = '*';
            str[n++] = ']';
        }
index 0a9628d..f4946c2 100644 (file)
--- a/opcode.h
+++ b/opcode.h
@@ -1360,7 +1360,7 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */
        Perl_ck_spair,          /* chomp */
        Perl_ck_null,           /* schomp */
        Perl_ck_defined,        /* defined */
-       Perl_ck_lfun,           /* undef */
+       Perl_ck_fun,            /* undef */
        Perl_ck_fun,            /* study */
        Perl_ck_lfun,           /* pos */
        Perl_ck_lfun,           /* preinc */
@@ -1746,7 +1746,7 @@ EXTCONST U32 PL_opargs[] = {
        0x00002b1d,     /* chomp */
        0x00009b9c,     /* schomp */
        0x00009b84,     /* defined */
-       0x00009b04,     /* undef */
+       0x0000fb04,     /* undef */
        0x00009b84,     /* study */
        0x00009b8c,     /* pos */
        0x00001164,     /* preinc */
index 0beba6a..592eceb 100644 (file)
@@ -103,7 +103,7 @@ schop               scalar chop             ck_null         stu%    S?
 chomp          chomp                   ck_spair        mTs%    L
 schomp         scalar chomp            ck_null         sTu%    S?
 defined                defined operator        ck_defined      isu%    S?
-undef          undef operator          ck_lfun         s%      S?
+undef          undef operator          ck_fun          s%      R?
 study          study                   ck_fun          su%     S?
 pos            match position          ck_lfun         stu%    S?