/* op.c
*
* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
* 2000, 2001, 2002, 2003, 2004, by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
*/
/*
* "You see: Mr. Drogo, he married poor Miss Primula Brandybuck. She was
* our Mr. Bilbo's first cousin on the mother's side (her mother being the
* youngest of the Old Took's daughters); and Mr. Drogo was his second
* cousin. So Mr. Frodo is his first *and* second cousin, once removed
* either way, as the saying is, if you follow me." --the Gaffer
*/
#include "EXTERN.h"
#define PERL_IN_OP_C
#include "perl.h"
#include "keywords.h"
#if defined(PL_OP_SLAB_ALLOC)
#ifndef PERL_SLAB_SIZE
#endif
void *
{
/*
* To make incrementing use count easy PL_OpSlab is an I32 *
* To make inserting the link to slab PL_OpPtr is I32 **
* So compute size in units of sizeof(I32 *) as that is how Pl_OpPtr increments
* Add an overhead for pointer to slab and round up as a number of pointers
*/
if ((PL_OpSpace -= sz) < 0) {
if (!PL_OpPtr) {
return NULL;
}
/* We reserve the 0'th I32 sized chunk as a use count */
/* Reduce size by the use count word, and by the size we need.
* Latter is to mimic the '-=' in the if() above
*/
/* Allocation pointer starts at the top.
Theory: because we build leaves before trunk allocating at end
means that at run time access is cache friendly upward
*/
}
assert( PL_OpSpace >= 0 );
/* Move the allocation pointer down */
(*PL_OpSlab)++; /* Increment use count of slab */
return (void *)(PL_OpPtr + 1);
}
void
{
if (--(*slab) == 0) {
# ifdef NETWARE
# endif
PL_OpSpace = 0;
}
}
}
#endif
/*
* In the following definition, the ", Nullop" is just to make the compiler
* think the expression is of the right type: croak actually does a Siglongjmp.
*/
Nullop ) \
STATIC char*
{
}
{
OP_DESC(o)));
return o;
}
{
return o;
}
{
return o;
}
STATIC void
{
}
STATIC void
{
cSVOPo_sv));
}
/* "register" allocation */
{
/* complain about "my $_" etc etc */
{
/* 1999-02-27 mjd@plover.com */
char *p;
/* The next block assumes the buffer is at least 205 chars
long. At present, it's always at least 256 chars. */
if (p-name > 200) {
p = name+199;
}
else {
p[1] = '\0';
}
/* Move everything else down one character */
for (; p-name > 2; p--)
*p = *(p-1);
}
}
/* check for duplicate declaration */
);
"Can't declare class for non-scalar %s in \"%s\"",
}
/* allocate a spare slot and store the name in that slot */
: Nullhv
),
0 /* not fake */
);
return off;
}
#ifdef USE_5005THREADS
/* find_threadsv is not reentrant */
{
char *p;
/* We currently only handle names of a single character */
if (!p)
return NOT_IN_PAD;
key = p - PL_threadsv_names;
if (svp)
else {
/*
* Some magic variables used to be automagically initialised
* in gv_fetchpv. Those which are now per-thread magicals get
* initialised here instead.
*/
switch (*name) {
case '_':
break;
case ';':
break;
case '&':
case '`':
case '\'':
/* FALL THROUGH */
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
/* FALL THROUGH */
/* XXX %! tied to Errno.pm needs to be added here.
* See gv_fetchpv(). */
/* case '!': */
default:
}
"find_threadsv: new SV %p for $%s%c\n",
}
return key;
}
#endif /* USE_5005THREADS */
/* Destructor */
void
{
return;
if (o->op_private & OPpREFCOUNTED) {
switch (o->op_type) {
case OP_LEAVESUB:
case OP_LEAVESUBLV:
case OP_LEAVEEVAL:
case OP_LEAVE:
case OP_SCOPE:
case OP_LEAVEWRITE:
if (OpREFCNT_dec(o)) {
return;
}
break;
default:
break;
}
}
}
}
/* COP* is not cleared by op_clear() so that we may track line
* numbers etc even after null() */
op_clear(o);
FreeOp(o);
}
void
{
switch (o->op_type) {
case OP_NULL: /* Was holding old type, if any. */
case OP_ENTEREVAL: /* Was holding hints. */
#ifdef USE_5005THREADS
case OP_THREADSV: /* Was holding index into thr->threadsv AV. */
#endif
o->op_targ = 0;
break;
#ifdef USE_5005THREADS
case OP_ENTERITER:
if (!(o->op_flags & OPf_SPECIAL))
break;
/* FALL THROUGH */
#endif /* USE_5005THREADS */
default:
break;
/* FALL THROUGH */
case OP_GVSV:
case OP_GV:
case OP_AELEMFAST:
/* not an OP_PADAV replacement */
#ifdef USE_ITHREADS
/* No GvIN_PAD_off(cGVOPo_gv) here, because other references
* may still exist on the pad */
}
#else
#endif
}
break;
case OP_METHOD_NAMED:
case OP_CONST:
#ifdef USE_ITHREADS
/** Bug #15654
Even if op_clear does a pad_free for the target of the op,
pad_free doesn't actually remove the sv that exists in the pad;
instead it lives on. This results in that it could be reused as
a target later on when the pad was reallocated.
**/
if(o->op_targ) {
o->op_targ = 0;
}
#endif
break;
case OP_GOTO:
case OP_NEXT:
case OP_LAST:
case OP_REDO:
break;
/* FALL THROUGH */
case OP_TRANS:
}
else {
}
break;
case OP_SUBST:
goto clear_pmop;
case OP_PUSHRE:
#ifdef USE_ITHREADS
/* No GvIN_PAD_off here, because other references may still
* exist on the pad */
}
#else
#endif
/* FALL THROUGH */
case OP_MATCH:
case OP_QR:
{
while (pmop) {
if (lastpmop)
else
break;
}
}
}
}
/* we use the "SAFE" version of the PM_ macros here
* since sv_clean_all might release some PMOPs
* after PL_regex_padav has been cleared
* and the clearing of PL_regex_padav needs to
* happen before sv_clean_all
*/
#ifdef USE_ITHREADS
if(PL_regex_pad) { /* We could be in destruction */
}
#endif
break;
}
if (o->op_targ > 0) {
o->op_targ = 0;
}
}
STATIC void
{
#ifdef USE_ITHREADS
#if 0
#endif
#else
#endif
}
}
void
{
return;
op_clear(o);
}
/* Contextualizers */
OP *
{
if (o->op_next)
return o->op_next;
/* establish postfix order */
if (kid->op_sibling)
else
}
}
else
o->op_next = o;
return o->op_next;
}
OP *
{
}
return o;
}
{
if (ckWARN(WARN_SYNTAX)) {
if (PL_copline != NOLINE)
}
}
return scalar(o);
}
OP *
{
/* assumes no premature commitment */
{
return o;
}
switch (o->op_type) {
case OP_REPEAT:
break;
case OP_OR:
case OP_AND:
case OP_COND_EXPR:
break;
case OP_SPLIT:
if (!kPMOP->op_pmreplroot)
deprecate_old("implicit split to @_");
}
/* FALL THROUGH */
case OP_MATCH:
case OP_QR:
case OP_SUBST:
case OP_NULL:
default:
}
break;
case OP_LEAVE:
case OP_LEAVETRY:
if (kid->op_sibling)
else
}
break;
case OP_SCOPE:
case OP_LINESEQ:
case OP_LIST:
if (kid->op_sibling)
else
}
break;
case OP_SORT:
}
return o;
}
OP *
{
char* useless = 0;
if (o->op_type == OP_NEXTSTATE
|| o->op_type == OP_SETSTATE
|| o->op_type == OP_DBSTATE
|| o->op_targ == OP_SETSTATE
|| o->op_targ == OP_DBSTATE)))
/* assumes no premature commitment */
{
return o;
}
if ((o->op_private & OPpTARGET_MY)
{
return scalar(o); /* As if inside SASSIGN */
}
switch (o->op_type) {
default:
break;
/* FALL THROUGH */
case OP_REPEAT:
if (o->op_flags & OPf_STACKED)
break;
goto func_ops;
case OP_SUBSTR:
if (o->op_private == 4)
break;
/* FALL THROUGH */
case OP_GVSV:
case OP_WANTARRAY:
case OP_GV:
case OP_PADSV:
case OP_PADAV:
case OP_PADHV:
case OP_PADANY:
case OP_AV2ARYLEN:
case OP_REF:
case OP_REFGEN:
case OP_SREFGEN:
case OP_DEFINED:
case OP_HEX:
case OP_OCT:
case OP_LENGTH:
case OP_VEC:
case OP_INDEX:
case OP_RINDEX:
case OP_SPRINTF:
case OP_AELEM:
case OP_AELEMFAST:
case OP_ASLICE:
case OP_HELEM:
case OP_HSLICE:
case OP_UNPACK:
case OP_PACK:
case OP_JOIN:
case OP_LSLICE:
case OP_ANONLIST:
case OP_ANONHASH:
case OP_SORT:
case OP_REVERSE:
case OP_RANGE:
case OP_FLIP:
case OP_FLOP:
case OP_CALLER:
case OP_FILENO:
case OP_EOF:
case OP_TELL:
case OP_GETSOCKNAME:
case OP_GETPEERNAME:
case OP_READLINK:
case OP_TELLDIR:
case OP_GETPPID:
case OP_GETPGRP:
case OP_GETPRIORITY:
case OP_TIME:
case OP_TMS:
case OP_LOCALTIME:
case OP_GMTIME:
case OP_GHBYNAME:
case OP_GHBYADDR:
case OP_GHOSTENT:
case OP_GNBYNAME:
case OP_GNBYADDR:
case OP_GNETENT:
case OP_GPBYNAME:
case OP_GPBYNUMBER:
case OP_GPROTOENT:
case OP_GSBYNAME:
case OP_GSBYPORT:
case OP_GSERVENT:
case OP_GPWNAM:
case OP_GPWUID:
case OP_GGRNAM:
case OP_GGRGID:
case OP_GETLOGIN:
case OP_PROTOTYPE:
break;
case OP_RV2GV:
case OP_RV2SV:
case OP_RV2AV:
case OP_RV2HV:
useless = "a variable";
break;
case OP_CONST:
else {
useless = "a constant";
/* don't warn on optimised away booleans, eg
* use constant Foo, 5; Foo || print; */
useless = 0;
/* the constants 0 and 1 are permitted as they are
conventionally used as dummies in constructs like
1 while some_condition_with_side_effects; */
useless = 0;
/* perl4's way of mixing documentation and code
(before the invention of POD) was based on a
trick to mix nroff and perl code. The trick was
built upon these three nroff macros being used in
void context. The pink camel has the details in
the script wrapman near page 319. */
useless = 0;
}
}
}
op_null(o); /* don't execute or even remember it */
break;
case OP_POSTINC:
break;
case OP_POSTDEC:
break;
case OP_OR:
case OP_AND:
case OP_COND_EXPR:
break;
case OP_NULL:
if (o->op_flags & OPf_STACKED)
break;
/* FALL THROUGH */
case OP_NEXTSTATE:
case OP_DBSTATE:
case OP_ENTERTRY:
case OP_ENTER:
break;
/* FALL THROUGH */
case OP_SCOPE:
case OP_LEAVE:
case OP_LEAVETRY:
case OP_LEAVELOOP:
case OP_LINESEQ:
case OP_LIST:
break;
case OP_ENTEREVAL:
scalarkids(o);
break;
case OP_REQUIRE:
/* all requires must return a boolean value */
/* FALL THROUGH */
case OP_SCALAR:
return scalar(o);
case OP_SPLIT:
if (!kPMOP->op_pmreplroot)
deprecate_old("implicit split to @_");
}
break;
}
return o;
}
OP *
{
}
return o;
}
OP *
{
/* assumes no premature commitment */
{
return o;
}
if ((o->op_private & OPpTARGET_MY)
{
return o; /* As if inside SASSIGN */
}
switch (o->op_type) {
case OP_FLOP:
case OP_REPEAT:
break;
case OP_OR:
case OP_AND:
case OP_COND_EXPR:
break;
default:
case OP_MATCH:
case OP_QR:
case OP_SUBST:
case OP_NULL:
break;
return gen_constant_list(o);
}
case OP_LIST:
listkids(o);
break;
case OP_LEAVE:
case OP_LEAVETRY:
if (kid->op_sibling)
else
}
break;
case OP_SCOPE:
case OP_LINESEQ:
if (kid->op_sibling)
else
}
break;
case OP_REQUIRE:
/* all requires must return a boolean value */
return scalar(o);
}
return o;
}
OP *
{
if (o) {
if (o->op_type == OP_LINESEQ ||
o->op_type == OP_LEAVETRY)
{
if (kid->op_sibling) {
}
}
}
o->op_flags &= ~OPf_PARENS;
if (PL_hints & HINT_BLOCK_SCOPE)
o->op_flags |= OPf_PARENS;
}
else
return o;
}
{
}
return o;
}
OP *
{
if (!o || PL_error_count)
return o;
if ((o->op_private & OPpTARGET_MY)
{
return o;
}
switch (o->op_type) {
case OP_UNDEF:
PL_modcount++;
return o;
case OP_CONST:
if (!(o->op_private & (OPpCONST_ARYBASE)))
goto nomod;
PL_eval_start = 0;
}
else if (!type) {
PL_compiling.cop_arybase = 0;
}
goto nomod;
else
break;
case OP_STUB:
if (o->op_flags & OPf_PARENS)
break;
goto nomod;
case OP_ENTERSUB:
!(o->op_flags & OPf_STACKED)) {
break;
}
else if (o->op_private & OPpENTERSUB_NOMOD)
return o;
else { /* lvalue subroutine call */
o->op_private |= OPpLVAL_INTRO;
/* Backward compatibility mode: */
o->op_private |= OPpENTERSUB_INARGS;
break;
}
else { /* Compile-time error message: */
goto skip_kids;
"panic: unexpected lvalue entersub "
while (kid->op_sibling)
/* Indirect call */
{
break;
}
"panic: unexpected lvalue entersub "
break; /* Postpone until runtime */
}
"Unexpected constant lvalue entersub "
/* Restore RV2CV to check lvalueness */
}
else
break;
}
if (!cv)
goto restore_2cv;
break;
}
}
/* FALL THROUGH */
default:
/* grep, foreach, subcalls, refgen */
break;
? "do block"
: (o->op_type == OP_ENTERSUB
? "non-lvalue subroutine call"
: OP_DESC(o))),
return o;
case OP_PREINC:
case OP_PREDEC:
case OP_POW:
case OP_MULTIPLY:
case OP_DIVIDE:
case OP_MODULO:
case OP_REPEAT:
case OP_ADD:
case OP_SUBTRACT:
case OP_CONCAT:
case OP_LEFT_SHIFT:
case OP_RIGHT_SHIFT:
case OP_BIT_AND:
case OP_BIT_XOR:
case OP_BIT_OR:
case OP_I_MULTIPLY:
case OP_I_DIVIDE:
case OP_I_MODULO:
case OP_I_ADD:
case OP_I_SUBTRACT:
if (!(o->op_flags & OPf_STACKED))
goto nomod;
PL_modcount++;
break;
case OP_COND_EXPR:
break;
case OP_RV2AV:
case OP_RV2HV:
return o; /* Treat \(@foo) like ordinary list. */
}
/* FALL THROUGH */
case OP_RV2GV:
if (scalar_mod_type(o, type))
goto nomod;
/* FALL THROUGH */
case OP_ASLICE:
case OP_HSLICE:
if (type == OP_LEAVESUBLV)
o->op_private |= OPpMAYBE_LVSUB;
/* FALL THROUGH */
case OP_AASSIGN:
case OP_NEXTSTATE:
case OP_DBSTATE:
break;
case OP_RV2SV:
/* FALL THROUGH */
case OP_GV:
case OP_AV2ARYLEN:
case OP_SASSIGN:
case OP_ANDASSIGN:
case OP_ORASSIGN:
case OP_AELEMFAST:
/* Needed if maint gets patch 19588
localize = -1;
*/
PL_modcount++;
break;
case OP_PADAV:
case OP_PADHV:
return o; /* Treat \(@foo) like ordinary list. */
if (scalar_mod_type(o, type))
goto nomod;
if (type == OP_LEAVESUBLV)
o->op_private |= OPpMAYBE_LVSUB;
/* FALL THROUGH */
case OP_PADSV:
PL_modcount++;
if (!type)
{ /* XXX DAPM 2002.08.25 tmp assert test */
PAD_COMPNAME_PV(o->op_targ));
}
break;
#ifdef USE_5005THREADS
case OP_THREADSV:
PL_modcount++; /* XXX ??? */
break;
#endif /* USE_5005THREADS */
case OP_PUSHMARK:
break;
case OP_KEYS:
if (type != OP_SASSIGN)
goto nomod;
goto lvalue_func;
case OP_SUBSTR:
goto nomod;
/* FALL THROUGH */
case OP_POS:
case OP_VEC:
if (type == OP_LEAVESUBLV)
o->op_private |= OPpMAYBE_LVSUB;
break;
case OP_AELEM:
case OP_HELEM:
if (type == OP_ENTERSUB &&
o->op_private |= OPpLVAL_DEFER;
if (type == OP_LEAVESUBLV)
o->op_private |= OPpMAYBE_LVSUB;
PL_modcount++;
break;
case OP_SCOPE:
case OP_LEAVE:
case OP_ENTER:
case OP_LINESEQ:
break;
case OP_NULL:
goto nomod;
break;
break;
}
/* FALL THROUGH */
case OP_LIST:
break;
case OP_RETURN:
if (type != OP_LEAVESUBLV)
goto nomod;
break; /* mod()ing was handled by ck_return() */
}
/* [20011101.069] File test operators interpret OPf_REF to mean that
their argument is a filehandle; thus \stat(".") should not set
it. AMS 20011102 */
return o;
if (type != OP_LEAVESUBLV)
else if (!type) {
o->op_private |= OPpLVAL_INTRO;
o->op_flags &= ~OPf_SPECIAL;
}
&& type != OP_LEAVESUBLV)
return o;
}
STATIC bool
{
switch (type) {
case OP_SASSIGN:
return FALSE;
/* FALL THROUGH */
case OP_PREINC:
case OP_PREDEC:
case OP_POSTINC:
case OP_POSTDEC:
case OP_I_PREINC:
case OP_I_PREDEC:
case OP_I_POSTINC:
case OP_I_POSTDEC:
case OP_POW:
case OP_MULTIPLY:
case OP_DIVIDE:
case OP_MODULO:
case OP_REPEAT:
case OP_ADD:
case OP_SUBTRACT:
case OP_I_MULTIPLY:
case OP_I_DIVIDE:
case OP_I_MODULO:
case OP_I_ADD:
case OP_I_SUBTRACT:
case OP_LEFT_SHIFT:
case OP_RIGHT_SHIFT:
case OP_BIT_AND:
case OP_BIT_XOR:
case OP_BIT_OR:
case OP_CONCAT:
case OP_SUBST:
case OP_TRANS:
case OP_READ:
case OP_SYSREAD:
case OP_RECV:
case OP_ANDASSIGN:
case OP_ORASSIGN:
return TRUE;
default:
return FALSE;
}
}
STATIC bool
{
switch (o->op_type) {
case OP_PIPE_OP:
case OP_SOCKPAIR:
if (argnum == 2)
return TRUE;
/* FALL THROUGH */
case OP_SYSOPEN:
case OP_OPEN:
case OP_SELECT: /* XXX c.f. SelectSaver.pm */
case OP_SOCKET:
case OP_OPEN_DIR:
case OP_ACCEPT:
if (argnum == 1)
return TRUE;
/* FALL THROUGH */
default:
return FALSE;
}
}
OP *
{
}
return o;
}
OP *
{
if (!o || PL_error_count)
return o;
switch (o->op_type) {
case OP_ENTERSUB:
!(o->op_flags & OPf_STACKED)) {
o->op_flags |= OPf_SPECIAL;
}
break;
case OP_COND_EXPR:
break;
case OP_RV2SV:
if (type == OP_DEFINED)
/* FALL THROUGH */
case OP_PADSV:
: OPpDEREF_SV);
}
break;
case OP_THREADSV:
break;
case OP_RV2AV:
case OP_RV2HV:
/* FALL THROUGH */
case OP_RV2GV:
if (type == OP_DEFINED)
break;
case OP_PADAV:
case OP_PADHV:
break;
case OP_SCALAR:
case OP_NULL:
break;
break;
case OP_AELEM:
case OP_HELEM:
: OPpDEREF_SV);
}
break;
case OP_SCOPE:
case OP_LEAVE:
case OP_ENTER:
case OP_LIST:
break;
break;
default:
break;
}
return scalar(o);
}
{
/* An attrlist is either a simple OP_CONST or an OP_LIST with kids,
* where the first kid is OP_PUSHMARK and the remaining ones
* are OP_CONST. We need to push the OP_CONST values.
*/
else {
}
}
return rop;
}
STATIC void
{
/* fake up C<use attributes $pkg,$rv,@attrs> */
ENTER; /* need to protect against side-effects of 'use' */
if (stash)
else
if (for_my) {
/* Don't force the C<use> if we don't need it. */
sizeof(ATTRSMODULE_PM)-1, 0);
; /* already in %INC */
else
Nullsv);
}
else {
dup_attrlist(attrs))));
}
}
STATIC void
{
if (!attrs)
return;
/* Ensure that attributes.pm is loaded. */
/* Need package name for method call. */
/* Build up the real arg-list. */
if (stash)
else
dup_attrlist(attrs)));
/* Fake up a method call to import */
/* Combine the ops. */
}
/*
=notfor apidoc apply_attrs_string
Attempts to apply a list of attributes specified by the C<attrstr> and
C<len> arguments to the subroutine identified by the C<cv> argument which
is expected to be associated with the package identified by the C<stashpv>
argument (see L<attributes>). It gets this wrong, though, in that it
does not correctly identify the boundaries of the individual attribute
specifications within C<attrstr>. This is not really intended for the
public API, but has to be listed here for systems such as AIX which
need an explicit export list for symbols. (It's called from XS code
in support of the C<ATTRS:> keyword from F<xsubpp>.) Patches to fix it
to respect attribute syntax properly would be welcome.
=cut
*/
void
{
if (!len) {
}
while (len) {
if (len) {
}
}
attrs)));
}
{
if (!o || PL_error_count)
return o;
return o;
} else if (attrs) {
}
o->op_private |= OPpOUR_INTRO;
return o;
}
type != OP_PUSHMARK)
{
OP_DESC(o),
return o;
}
/* check for C<my Dog $spot> when deciding package */
if (!stash)
stash = PL_curstash;
}
o->op_private |= OPpLVAL_INTRO;
return o;
}
OP *
{
int maybe_scalar = 0;
/* [perl #17376]: this appears to be premature, and results in code such as
C< our(%x); > executing in list mode rather than void mode */
#if 0
if (o->op_flags & OPf_PARENS)
list(o);
else
maybe_scalar = 1;
#else
maybe_scalar = 1;
#endif
if (attrs)
if (rops) {
o->op_private |= OPpLVAL_INTRO;
}
else
}
return o;
}
OP *
{
}
OP *
{
if (o)
o->op_flags |= OPf_PARENS;
return o;
}
OP *
{
OP *o;
? "@array" : "%hash");
"Applying %s to %s will act on scalar(%s)",
}
{
}
else
return o;
}
else
}
OP *
{
if (!o)
return o;
/* XXX need to optimize away NOT NOT here? Or do we let optimizer do it? */
}
OP *
{
if (o) {
}
else if (o->op_type == OP_LINESEQ) {
}
else
}
return o;
}
/* XXX kept for BINCOMPAT only */
void
{
}
int
{
/* If there were syntax errors, don't try to start a block */
if (PL_yynerrs) return retval;
SAVEHINTS();
PL_hints &= ~HINT_BLOCK_SCOPE;
}
}
return retval;
}
OP*
{
/* If there were syntax errors, don't try to close a block */
if (PL_yynerrs) return retval;
if (needblockscope)
pad_leavemy();
return retval;
}
{
#ifdef USE_5005THREADS
return o;
#else
#endif /* USE_5005THREADS */
}
void
{
if (PL_in_eval) {
if (PL_eval_root)
return;
((PL_in_eval & EVAL_KEEPERR)
? OPf_SPECIAL : 0), o);
PL_eval_root->op_next = 0;
}
else {
PL_comppad_name = 0;
PL_compcv = 0;
FreeOp(o);
return;
}
PL_main_root->op_next = 0;
PL_compcv = 0;
/* Register with debugger */
if (PERLDB_INTER) {
if (cv) {
dSP;
}
}
}
}
OP *
{
if (o->op_flags & OPf_PARENS)
/* [perl #17376]: this appears to be premature, and results in code such as
C< our(%x); > executing in list mode rather than void mode */
#if 0
list(o);
#else
;
#endif
else {
if (ckWARN(WARN_PARENTHESIS)
{
char *s = PL_bufptr;
/* some heuristics to detect a potential error */
while (*s && (strchr(", \t\n", *s)))
s++;
while (1) {
if (*s && strchr("@$%*", *s) && *++s
&& (isALNUM(*s) || UTF8_IS_CONTINUED(*s))) {
s++;
while (*s && (isALNUM(*s) || UTF8_IS_CONTINUED(*s)))
s++;
while (*s && (strchr(", \t\n", *s)))
s++;
}
else
break;
}
"Parentheses missing around \"%s\" list",
: "local");
}
}
}
if (lex)
o = my(o);
else
return o;
}
OP *
{
#ifdef USE_5005THREADS
#else
#endif /* USE_5005THREADS */
}
return o;
}
OP *
{
scalar(o);
/* integerize op, unless it happens to be C<-foo>.
* XXX should pp_i_negate() do magic string negation instead? */
{
}
goto nope;
switch (type) {
case OP_NEGATE:
/* XXX might want a ck_negate() for this */
break;
case OP_UCFIRST:
case OP_LCFIRST:
case OP_UC:
case OP_LC:
case OP_SLT:
case OP_SGT:
case OP_SLE:
case OP_SGE:
case OP_SCMP:
/* XXX what about the numeric ops? */
if (PL_hints & HINT_LOCALE)
goto nope;
}
if (PL_error_count)
goto nope; /* Don't try to run w/ errors */
{
goto nope;
}
}
o->op_next = 0;
sv = *(PL_stack_sp--);
(void)SvREFCNT_inc(sv);
SvTEMP_off(sv);
}
op_free(o);
nope:
return o;
}
OP *
{
list(o);
if (PL_error_count)
return o; /* Don't attempt to run with errors */
o->op_next = 0;
pp_pushmark();
pp_anonlist();
o->op_seq = 0; /* needs to be revisited in peep() */
linklist(o);
return list(o);
}
OP *
{
else
return o;
return fold_constants(o);
}
/* List constructors */
OP *
{
if (!first)
return last;
if (!last)
return first;
{
}
else {
}
return first;
}
OP *
{
if (!first)
if (!last)
}
OP *
{
if (!first)
return last;
if (!last)
return first;
}
else {
}
}
return last;
}
}
/* Constructors */
OP *
{
}
OP *
{
op_null(o);
return o;
}
OP *
{
else if (first)
if (!last)
}
}
OP *
{
OP *o;
o->op_next = o;
scalar(o);
}
OP *
{
if (!first)
}
OP *
{
if (!first)
if (!last) {
}
else {
}
}
static int
uvcompare(const void *a, const void *b)
{
return -1;
return 1;
return -1;
return 1;
return 0;
}
OP *
{
register I32 i;
register I32 j;
register short *tbl;
o->op_private |= OPpTRANS_FROM_UTF;
o->op_private |= OPpTRANS_TO_UTF;
if (!from_utf) {
}
}
/* There are several snags with this code on EBCDIC:
1. 0xFF is a legal UTF-EBCDIC byte (there are no illegal bytes).
2. scan_const() in toke.c has encoded chars in native encoding which makes
ranges at least in EBCDIC 0..255 range the bottom odd.
*/
if (complement) {
i = 0;
while (t < tend) {
t += ulen;
t++;
t += ulen;
}
else {
}
i++;
}
for (j = 0; j < i; j++) {
if (diff > 0) {
if (diff > 1) {
}
}
}
{
}
}
}
if (!squash) {
{
o->op_private |= OPpTRANS_IDENTICAL;
}
}
/* see if we need more "t" chars */
t += ulen;
t++;
t += ulen;
}
else
}
/* now see if we need more "r" chars */
if (r < rend) {
r += ulen;
r++;
r += ulen;
}
else
}
else {
if (!havefinal++)
}
}
/* now see which range will peter our first, if either. */
else
if (rfirst == 0xffffffff) {
if (diff > 0)
else
}
else {
if (diff > 0)
(long)rfirst);
else
if (!grows)
}
}
if (del)
if (max > 0xffff)
bits = 32;
else if (max > 0xff)
bits = 16;
else
bits = 8;
if (transv)
if (grows)
o->op_private |= OPpTRANS_GROWS;
if (tsave)
if (rsave)
return o;
}
if (complement) {
tbl[t[i]] = -1;
for (i = 0, j = 0; i < 256; i++) {
if (!tbl[i]) {
if (del)
tbl[i] = -2;
else if (rlen)
tbl[i] = r[j-1];
else
tbl[i] = (short)i;
}
else {
if (i < 128 && r[j] >= 128)
grows = 1;
tbl[i] = r[j++];
}
}
}
if (!del) {
if (!rlen) {
j = rlen;
if (!squash)
o->op_private |= OPpTRANS_IDENTICAL;
}
j = rlen - 1;
else
tbl[0x101+i] = r[j+i];
}
}
else {
if (!squash)
o->op_private |= OPpTRANS_IDENTICAL;
}
o->op_private |= OPpTRANS_IDENTICAL;
}
for (i = 0; i < 256; i++)
tbl[i] = -1;
if (del) {
if (tbl[t[i]] == -1)
tbl[t[i]] = -2;
continue;
}
--j;
}
if (tbl[t[i]] == -1) {
if (t[i] < 128 && r[j] >= 128)
grows = 1;
tbl[t[i]] = r[j];
}
}
}
if (grows)
o->op_private |= OPpTRANS_GROWS;
return o;
}
OP *
{
if (PL_hints & HINT_RE_TAINT)
if (PL_hints & HINT_LOCALE)
#ifdef USE_ITHREADS
{
} else {
}
}
#endif
/* link into pm list */
}
}
OP *
{
}
}
else {
: OP_REGCMAYBE),0,expr);
? (OPf_SPECIAL | OPf_KIDS)
: OPf_KIDS);
/* establish postfix order */
}
else {
}
}
if (repl) {
curop = 0;
}
#ifdef USE_5005THREADS
&& strchr("&`'123456789+",
{
curop = 0;
}
#endif /* USE_5005THREADS */
else {
#ifdef USE_5005THREADS
repl_has_vars = 1;
break;
}
#else
repl_has_vars = 1;
break;
}
#endif /* USE_5005THREADS */
break;
break;
}
repl_has_vars = 1;
}
; /* Okay here, dangerous in newASSIGNOP */
else
break;
}
}
}
&& !(repl_has_vars
}
else {
}
/* establish postfix order */
}
}
}
OP *
{
}
OP *
{
if (sv)
}
OP *
{
#ifdef USE_ITHREADS
if (gv)
#else
#endif
}
OP *
{
}
void
{
if (o) {
char *name;
op_free(o);
}
else {
deprecate("\"package\" with no arguments");
}
PL_copline = NOLINE;
}
void
{
}
else {
/* Make copy of idop so we don't free it twice */
/* Fake up a method call to VERSION */
}
}
}
else {
/* Make copy of idop so we don't free it twice */
}
/* Fake up the BEGIN {}, which does its thing immediately. */
/* The "did you use incorrect case?" warning used to be here.
* The problem is that on case-insensitive filesystems one
* might get false positives for "use" (and "require"):
* "use Strict" or "require CARP" will work. This causes
* portability problems for the script: in case-strict
* filesystems the script will stop working.
*
* The "incorrect case" warning checked whether "use Foo"
* imported "Foo" to your namespace, but that is wrong, too:
* there is no requirement nor promise in the language that
* a Foo.pm should or would contain anything in package "Foo".
*
* There is very little Configure-wise that can be done, either:
* the case-sensitivity of the build filesystem of Perl does not
* help in guessing the case-sensitivity of the runtime environment.
*/
PL_copline = NOLINE;
PL_cop_seqmax++; /* Purely for B::*'s benefit */
}
/*
=head1 Embedding Functions
=for apidoc load_module
Loads the module whose name is pointed to by the string part of name.
Note that the actual module name, not its filename, should be given.
PERL_LOADMOD_DENY, PERL_LOADMOD_NOIMPORT, or PERL_LOADMOD_IMPORT_OPS
(or 0 for no flags). ver, if specified, provides version semantics
similar to C<use Foo::Bar VERSION>. The optional trailing SV*
arguments can be used to specify arguments to the module's import()
method, similar to C<use Foo::Bar VERSION LIST>.
=cut */
void
{
}
#ifdef PERL_IMPLICIT_CONTEXT
void
{
dTHX;
}
#endif
void
{
if (ver) {
}
else
if (flags & PERL_LOADMOD_NOIMPORT) {
}
else if (flags & PERL_LOADMOD_IMPORT_OPS) {
}
else {
while (sv) {
}
}
{
}
}
OP *
{
gv))))));
}
else {
}
return doop;
}
OP *
{
}
{
if (!o)
return TRUE;
if (o->op_type == OP_COND_EXPR) {
if (t && f)
return TRUE;
if (t || f)
yyerror("Assignment to both a list and a scalar");
return FALSE;
}
o->op_private & OPpLVAL_INTRO)
return FALSE;
return TRUE;
return TRUE;
return FALSE;
return FALSE;
}
OP *
{
OP *o;
if (optype) {
}
else {
}
}
if (list_assignment(left)) {
PL_modcount = 0;
if (PL_eval_start)
PL_eval_start = 0;
else {
return Nullop;
}
/* optimise C<my @x = ()> to C<my @x>, and likewise for hashes */
{
return left;
}
{
o->op_private |= OPpASSIGN_HASH;
break;
}
}
/* PL_generation sorcery:
* an assignment like ($a,$b) = ($c,$d) is easier than
* ($a,$b) = ($c,$a), since there is no need for temporary vars.
* To detect whether there are common vars, the global var
* PL_generation is incremented for each assign op we compile.
* Then, while compiling the assign op, we run through all the
* variables on both sides of the assignment, setting a spare slot
* in each of them to PL_generation. If any of them already have
* that value, we know we've got commonality. We could use a
* single bit marker, but then we'd have to make 2 passes, first
* to clear the flag, then to test and set it. To find somewhere
* to store these values, evil chicanery is done with SvCUR().
*/
break;
}
{
== PL_generation)
break;
}
break;
break;
}
#ifdef USE_ITHREADS
#else
#endif
break;
}
}
else
break;
}
}
if (curop != o)
o->op_private |= OPpASSIGN_COMMON;
}
{
!(o->op_private & OPpASSIGN_COMMON) )
{
#ifdef USE_ITHREADS
#else
#endif
op_free(o); /* blow off assign */
/* "I don't know and I don't care." */
return right;
}
}
else {
if (PL_modcount < RETURN_UNLIMITED_NUMBER &&
{
}
}
}
}
return o;
}
if (!right)
}
else {
if (PL_eval_start)
PL_eval_start = 0;
else {
op_free(o);
return Nullop;
}
}
return o;
}
OP *
{
}
else {
}
#ifdef NATIVE_HINTS
#endif
if (label) {
}
else
else
if (PL_copline == NOLINE)
else {
PL_copline = NOLINE;
}
#ifdef USE_ITHREADS
#else
#endif
}
}
}
OP *
{
}
{
OP *o;
/* optimize "!a && b" to "a || b", and "!a || b" to "a && b" */
else
o = first;
if (o->op_next)
op_free(o);
}
}
return other;
}
else {
return first;
}
}
{
case OP_NULL:
{
}
break;
case OP_SASSIGN:
{
}
break;
}
if (warnop) {
"Value of %s%s can be \"0\"; test with defined()",
? " construct" : "() operator"));
}
}
if (!other)
return first;
/* establish postfix order */
return o;
}
OP *
{
OP *o;
if (!falseop)
if (!trueop)
}
return trueop;
}
else {
return falseop;
}
}
logop);
/* establish postfix order */
return o;
}
OP *
{
OP *o;
linklist(o); /* blow off optimizer unless constant */
return o;
}
OP *
{
OP* o;
if (expr) {
return block; /* do {} while 0 does once */
case OP_NULL:
break;
case OP_SASSIGN:
break;
}
}
}
/* if block is null, the next append_elem() would put UNSTACK, a scalar
* op, in listop. This is wrong. [perl #27024] */
if (!block)
if (listop)
if (o == listop)
o = scope(o);
return o;
}
OP *
Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP *loop, I32 whileline, OP *expr, OP *block, OP *cont)
{
OP *o;
case OP_NULL:
break;
case OP_SASSIGN:
break;
}
}
if (!block)
else if (cont) {
}
if (cont) {
}
if (expr) {
if (!next)
}
if (expr) {
return Nullop; /* listop already freed by new_logop */
}
if (listop)
}
else
o = listop;
if (!loop) {
loop->op_private = 0;
}
o->op_private |= loopflags;
if (next)
else
return o;
}
OP *
{
if (sv) {
}
}
iterflags |= OPf_SPECIAL;
}
else
}
else {
#ifdef USE_5005THREADS
iterflags |= OPf_SPECIAL;
#else
#endif
}
iterflags |= OPf_STACKED;
}
{
/* Basically turn for($x..$y) into the same as for($x,$y), but we
* set the STACKED flag to indicate that these values are to be
*/
iterflags |= OPf_STACKED;
}
else {
}
/* for my $x () sets OPpLVAL_INTRO;
* for our $x () sets OPpOUR_INTRO; both only used by Deparse.pm */
#ifdef PL_OP_SLAB_ALLOC
{
}
#else
#endif
}
OP*
{
OP *o;
/* "last()" means "last" */
else {
: ""));
}
}
else {
/* Check whether it's going to be a goto &function */
}
return o;
}
/*
=for apidoc cv_undef
Clear out all the active components of a CV. This can happen either
by an explicit C<undef &foo>, or by the reference count going to zero.
In the former case, we keep the CvOUTSIDE pointer, so that any anonymous
children can still follow the full lexical scope chain.
=cut
*/
void
{
#ifdef USE_5005THREADS
}
#endif /* USE_5005THREADS */
#ifdef USE_ITHREADS
/* for XSUBs CvFILE point directly to static memory; __FILE__ */
}
#endif
#ifdef USE_5005THREADS
#else
#endif /* USE_5005THREADS */
}
/* remove CvOUTSIDE unless this is an undef rather than a free */
if (!CvWEAKOUTSIDE(cv))
}
}
}
/* delete all flags except WEAKOUTSIDE */
}
void
{
if (gv)
if (name)
else
if (p)
else
}
}
/*
=head1 Optree Manipulation Functions
=for apidoc cv_const_sv
If C<cv> is a constant sub eligible for inlining. returns the constant
value returned by the sub. Otherwise, returns NULL.
Constant subs can be created with C<newCONSTSUB> or as described in
L<perlsub/"Constant Functions">.
=cut
*/
SV *
{
return Nullsv;
}
SV *
{
if (!o)
return Nullsv;
for (; o; o = o->op_next) {
return sv;
if (o->op_next != o) {
continue;
if (type == OP_DBSTATE)
continue;
}
break;
if (sv)
return Nullsv;
if (!sv)
return Nullsv;
/* We get here only from cv_clone2() while creating a closure.
Copy the const value here instead of in cv_clone2 so that
SvREADONLY_on doesn't lead to problems when leaving
scope.
*/
}
return Nullsv;
}
else
return Nullsv;
}
if (sv)
return sv;
}
void
{
if (o)
SAVEFREEOP(o);
if (proto)
if (attrs)
if (block)
}
CV *
{
}
CV *
{
char *name;
char *aname;
}
else
SVt_PVCV);
if (o)
SAVEFREEOP(o);
if (proto)
if (attrs)
maximum a prototype before. */
&& ckWARN_d(WARN_PROTOTYPE))
{
}
}
if (ps)
else
goto done;
}
#ifdef GV_UNIQUE_CHECK
}
#endif
else
if (cv) {
#ifdef GV_UNIQUE_CHECK
}
#endif
/* if the subroutine doesn't exist and wasn't pre-declared
* with a prototype, assume it will be AUTOLOADed,
* skipping the prototype check
*/
/* already defined (or promised)? */
/* might have had built-in attrs applied */
}
/* just a "sub foo;" when &foo is already defined */
goto done;
}
/* ahem, death to those who redefine active sort subs */
if (block) {
if (ckWARN(WARN_REDEFINE)
{
if (PL_copline != NOLINE)
: "Subroutine %s redefined", name);
}
}
}
}
if (const_sv) {
if (cv) {
CvCONST_on(cv);
}
else {
}
goto done;
}
if (attrs) {
/* Need to do a C<use attributes $stash_of_cv,\&cv,@attrs>
* before we clobber PL_compcv.
*/
/* Might have had built-in attributes applied -- propagate them. */
else
stash = PL_curstash;
}
else {
/* possibly about to re-define existing subr -- ignore old cv */
else
stash = PL_curstash;
}
}
if (cv) { /* must reuse cv if autoloaded */
if (!block) {
/* got here with just attrs -- work done, so bug out */
goto done;
}
/* transfer PL_compcv to cv */
if (!CvWEAKOUTSIDE(cv))
/* inner references to PL_compcv must be fixed up ... */
/* ... before we throw it away */
if (PERLDB_INTER)/* Advice debugger on the new sub. */
}
else {
if (name) {
}
}
#ifdef USE_5005THREADS
}
#endif /* USE_5005THREADS */
if (ps)
if (PL_error_count) {
if (name) {
s = s ? s+1 : name;
if (strEQ(s, "BEGIN")) {
char *not_safe =
"BEGIN not safe after errors--compilation aborted";
if (PL_in_eval & EVAL_KEEPERR)
else {
/* force display of errors found but not reported */
}
}
}
}
if (!block)
goto done;
}
else {
/* This makes sub {}; work as expected. */
}
}
/* now that optimizer has done its work, adjust pad values */
CvCONST_on(cv);
}
char *s;
{
dSP;
}
}
s++;
else
s = tname;
if (*s != 'B' && *s != 'E' && *s != 'C' && *s != 'I')
goto done;
if (strEQ(s, "BEGIN")) {
if (!PL_beginav)
PL_beginav = newAV();
}
if (!PL_endav)
}
if (!PL_checkav)
PL_checkav = newAV();
}
if (!PL_initav)
}
}
done:
PL_copline = NOLINE;
return cv;
}
/* XXX unsafe for threads if eval_owner isn't held */
/*
=for apidoc newCONSTSUB
Creates a constant sub equivalent to Perl C<sub FOO () { 123 }> which is
eligible for inlining at compile-time.
=cut
*/
CV *
{
SAVEHINTS();
PL_hints &= ~HINT_BLOCK_SCOPE;
if (stash) {
PL_curstash = stash;
}
CvCONST_on(cv);
if (stash)
return cv;
}
/*
=for apidoc U||newXS
Used by C<xsubpp> to hook up XSUBs as Perl subs.
=cut
*/
CV *
{
/* just a cached method */
cv = 0;
}
/* already defined (or promised) */
if (PL_copline != NOLINE)
: "Subroutine %s redefined"
,name);
}
cv = 0;
}
}
if (cv) /* must reuse cv if autoloaded */
else {
if (name) {
}
}
#ifdef USE_5005THREADS
#endif /* USE_5005THREADS */
(void)gv_fetchfile(filename);
an external constant string */
if (name) {
if (s)
s++;
else
s = name;
if (*s != 'B' && *s != 'E' && *s != 'C' && *s != 'I')
goto done;
if (strEQ(s, "BEGIN")) {
if (!PL_beginav)
PL_beginav = newAV();
}
else if (strEQ(s, "END")) {
if (!PL_endav)
}
else if (strEQ(s, "CHECK")) {
if (!PL_checkav)
PL_checkav = newAV();
}
else if (strEQ(s, "INIT")) {
if (!PL_initav)
}
}
else
done:
return cv;
}
void
{
char *name;
if (o)
else
name = "STDOUT";
#ifdef GV_UNIQUE_CHECK
}
#endif
GvMULTI_on(gv);
if (ckWARN(WARN_REDEFINE)) {
if (PL_copline != NOLINE)
}
}
op_free(o);
PL_copline = NOLINE;
}
OP *
{
}
OP *
{
}
OP *
{
}
OP *
{
newSVOP(OP_ANONCODE, 0,
}
OP *
{
switch (o->op_type) {
case OP_PADSV:
case OP_RV2SV:
break;
default:
if (ckWARN_d(WARN_INTERNAL))
break;
}
return o;
}
OP *
{
switch (o->op_type) {
case OP_PADSV:
case OP_PADAV:
case OP_RV2SV:
case OP_RV2AV:
break;
default:
if (ckWARN_d(WARN_INTERNAL))
break;
}
return o;
}
OP *
{
return o;
}
&& ckWARN(WARN_DEPRECATED)) {
"Using an array as a reference is deprecated");
}
}
OP *
{
}
OP *
{
return o;
}
&& ckWARN(WARN_DEPRECATED)) {
"Using a hash as a reference is deprecated");
}
}
OP *
{
/* STUB */
return o;
}
OP *
{
}
OP *
{
return o;
}
o->op_flags |= OPpDONE_SVREF;
return o;
}
}
/* Check routines. */
OP *
{
return o;
}
OP *
{
|| o->op_type == OP_BIT_AND
|| o->op_type == OP_BIT_XOR))
{
if (ckWARN(WARN_PRECEDENCE))
"Possible precedence problem on bitwise %c operator",
);
}
return o;
}
OP *
{
o->op_flags |= OPf_STACKED;
return o;
}
OP *
{
if (newop &&
(newop->op_sibling ||
return o;
}
}
return ck_fun(o);
}
OP *
{
o = ck_fun(o);
o->op_private = 0;
case OP_ASLICE:
o->op_flags |= OPf_SPECIAL;
/* FALL THROUGH */
case OP_HSLICE:
o->op_private |= OPpSLICE;
break;
case OP_AELEM:
o->op_flags |= OPf_SPECIAL;
/* FALL THROUGH */
case OP_HELEM:
break;
default:
OP_DESC(o));
}
}
return o;
}
OP *
{
#ifdef VMS
#endif
return ck_fun(o);
}
OP *
{
op_free(o);
}
return ck_fun(o);
}
return o;
}
OP *
{
if (!kid) {
op_null(o);
}
op_free(o);
enter->op_private = 0;
/* establish postfix order */
o->op_type = OP_LEAVETRY;
return o;
}
else
}
else {
op_free(o);
}
return o;
}
OP *
{
#ifdef VMS
if (table) {
o->op_private |= OPpEXIT_VMSISH;
}
#endif
return ck_fun(o);
}
OP *
{
if (o->op_flags & OPf_STACKED) {
o = ck_fun(o);
}
else
o = listkids(o);
return o;
}
OP *
{
o = ck_fun(o);
OP_DESC(o));
o->op_private |= OPpEXISTS_SUB;
}
o->op_flags |= OPf_SPECIAL;
OP_DESC(o));
}
return o;
}
#if 0
OP *
{
o = fold_constants(o);
return o;
}
#endif
OP *
{
char *name;
int iscv;
/* Is it a constant from cv_const_sv()? */
switch (o->op_type) {
case OP_RV2SV:
badtype = "a SCALAR";
break;
case OP_RV2AV:
badtype = "an ARRAY";
break;
case OP_RV2HV:
{
break;
}
}
badtype = "a HASH";
}
break;
case OP_RV2CV:
badtype = "a CODE";
break;
}
if (badtype)
return o;
}
switch (o->op_type) {
case OP_RV2SV:
badthing = "a SCALAR";
break;
case OP_RV2AV:
badthing = "an ARRAY";
break;
case OP_RV2HV:
badthing = "a HASH";
break;
}
if (badthing)
"Can't use bareword (\"%s\") as %s ref while \"strict refs\" in use",
}
/*
* This is a little tricky. We only want to add the symbol if we
* didn't add it in the lexer. Otherwise we get duplicate strict
* warnings. But if we didn't add it in the lexer, we must at
* least pretend like we wanted to add it even if it existed before,
* or we get possible typo warnings. OPpCONST_ENTERED says
* whether the lexer already added THIS instance of this symbol.
*/
do {
? SVt_PVCV
? SVt_PV
? SVt_PVAV
? SVt_PVHV
: SVt_PVGV);
if (gv) {
#ifdef USE_ITHREADS
/* XXX hack: dependence on sizeof(PADOP) <= sizeof(SVOP) */
#else
#endif
kid->op_private = 0;
}
}
return o;
}
OP *
{
/* nothing */
}
op_free(o);
o = newop;
}
else {
if ((PL_hints & HINT_FILETEST_ACCESS) &&
o->op_private |= OPpFT_ACCESS;
}
}
else {
op_free(o);
else
}
return o;
}
OP *
{
if (o->op_flags & OPf_STACKED) {
oa &= ~OA_OPTIONAL;
else
return no_fh_allowed(o);
}
{
}
numargs++;
switch (oa & 7) {
case OA_SCALAR:
/* list seen where single (scalar) arg expected? */
{
}
break;
case OA_LIST:
if (oa < 16) {
kid = 0;
continue;
}
else
break;
case OA_AVREF:
"Useless use of %s with no values",
{
}
break;
case OA_HVREF:
{
}
break;
case OA_CVREF:
{
kid->op_sibling = 0;
}
break;
case OA_FILEREF:
{
SVt_PVIO) );
}
/* neophyte patrol: open(<FH>), close(<FH>) etc. */
}
else {
/* is this op a FH constructor? */
if (is_handle_constructor(o,numargs)) {
flags = 0;
/* Set a flag to tell rv2gv to vivify
* need to "prove" flag does not mean something
* else already - NI-S 1999/05/07
*/
/*XXX DAPM 2002.08.25 tmp assert test */
/* SvCUR of a pad namesv can't be trusted
* (see PL_generation), so calc its length
* manually */
if (name)
}
{
}
{
name = 0;
char *a =
"[]" : "{}";
/* packagevar $a[] or $h{} */
if (gv)
tmpstr =
"%s%c...%c",
a[0], a[1]);
}
/* lexicalvar $a[] or $h{} */
char *padname =
if (padname)
tmpstr =
"%s%c...%c",
padname + 1,
a[0], a[1]);
}
if (tmpstr) {
}
}
if (!name) {
name = "__ANONIO__";
len = 10;
}
}
if (name) {
if (*name != '$')
}
}
kid->op_sibling = 0;
}
}
break;
case OA_SCALARREF:
break;
}
oa >>= 4;
}
o->op_private |= numargs;
if (kid)
return too_many_arguments(o,OP_DESC(o));
listkids(o);
}
op_free(o);
}
if (oa) {
while (oa & OA_OPTIONAL)
oa >>= 4;
return too_few_arguments(o,OP_DESC(o));
}
return o;
}
OP *
{
o = ck_fun(o);
{
}
#if !defined(PERL_EXTERNAL_GLOB)
/* XXX this can be tightened up and made more failsafe. */
}
#endif /* PERL_EXTERNAL_GLOB */
append_elem(OP_GLOB, o,
append_elem(OP_LIST, o,
return o;
}
scalarkids(o);
return o;
}
OP *
{
if (o->op_flags & OPf_STACKED) {
OP* k;
o = ck_sort(o);
kid = k;
}
o->op_flags &= ~OPf_STACKED;
}
if (type == OP_MAPWHILE)
else
o = ck_fun(o);
if (PL_error_count)
return o;
return too_few_arguments(o,OP_DESC(o));
}
OP *
{
if (kid)
}
return ck_fun(o);
}
OP *
{
/* XXX length optimization goes here */
return ck_fun(o);
}
OP *
{
}
OP *
{
case OP_RV2AV:
/* This is needed for
if (defined %stash::)
to work. Do not break Tk.
*/
break; /* Globals via GV can be undef */
case OP_PADAV:
case OP_AASSIGN: /* Is this a good idea? */
"defined(@array) is deprecated");
"\t(Maybe you should just omit the defined()?)\n");
break;
case OP_RV2HV:
/* This is needed for
if (defined %stash::)
to work. Do not break Tk.
*/
break; /* Globals via GV can be undef */
case OP_PADHV:
"defined(%%hash) is deprecated");
"\t(Maybe you should just omit the defined()?)\n");
break;
default:
/* no warning */
break;
}
}
return ck_rfun(o);
}
OP *
{
}
OP *
{
if (!kid) {
o = force_list(o);
}
}
}
if (!kid)
return listkids(o);
}
OP *
{
/* has a disposable target? */
/* Cannot steal the second time! */
{
/* Can just relocate the target. */
{
/* Now we do not need PADSV and SASSIGN. */
op_free(o);
return kid;
}
}
/* optimise C<my $x = undef> to C<my $x> */
{
op_free(o);
return kkid;
}
}
return o;
}
OP *
{
o->op_private |= OPpRUNTIME;
return o;
}
OP *
{
}
else {
}
op_free(o);
return cmop;
}
}
return o;
}
OP *
{
return o;
}
OP *
{
if (table) {
o->op_private |= OPpOPEN_IN_RAW;
o->op_private |= OPpOPEN_IN_CRLF;
}
o->op_private |= OPpOPEN_OUT_RAW;
o->op_private |= OPpOPEN_OUT_CRLF;
}
}
if (o->op_type == OP_BACKTICK)
return o;
{
/* In case of three-arg dup open remove strictness
* from the last arg if it is a bareword. */
char *mode;
}
return ck_fun(o);
}
OP *
{
o->op_private |= OPpREPEAT_DOLIST;
}
else
scalar(o);
return o;
}
OP *
{
char *s;
if (*s == ':' && s[1] == ':') {
*s = '/';
}
}
}
else
}
}
/* handle override, if any */
op_free(o);
gv))))));
}
return ck_fun(o);
}
OP *
{
}
return o;
}
#if 0
OP *
{
/* STUB */
return o;
}
#endif
OP *
{
o->op_type = OP_SSELECT;
o = ck_fun(o);
return fold_constants(o);
}
}
o = ck_fun(o);
return o;
}
OP *
{
op_free(o);
#ifdef USE_5005THREADS
}
else {
}
#else
#endif /* USE_5005THREADS */
}
}
OP *
{
simplify_sort(o);
}
k->op_next = 0;
/* don't descend into loops */
else if (k->op_type == OP_ENTERLOOP
|| k->op_type == OP_ENTERITER)
{
}
}
}
else
}
CALL_PEEP(k);
}
else
o->op_flags |= OPf_SPECIAL;
}
}
/* provide list context for arguments */
return o;
}
STATIC void
{
OP *k;
int reversed;
if (!(o->op_flags & OPf_STACKED))
return;
return;
case OP_NCMP:
case OP_I_NCMP:
case OP_SCMP:
break;
default:
return;
}
k = kid; /* remember this node*/
return;
return;
return;
reversed = 0;
reversed = 1;
else
return;
kid = k; /* back to cmp */
return;
return;
|| ( reversed
return;
if (reversed)
o->op_private |= OPpSORT_REVERSE;
o->op_private |= OPpSORT_NUMERIC;
}
OP *
{
if (o->op_flags & OPf_STACKED)
return no_fh_allowed(o);
if (!kid) {
}
kid->op_sibling = 0;
}
"Use of /g modifier is meaningless in split");
}
if (!kid->op_sibling)
if (!kid->op_sibling)
if (kid->op_sibling)
return too_many_arguments(o,OP_DESC(o));
return o;
}
OP *
{
if (ckWARN(WARN_SYNTAX)) {
"/%s/ should probably be written as \"%s\"",
}
}
return ck_fun(o);
}
OP *
{
char *proto = 0;
int optional = 0;
char *e = 0;
o->op_private |= OPpENTERSUB_HASTARG;
if (!cv)
}
}
}
o->op_private &= ~OPpCONST_STRICT;
}
}
o->op_private |= OPpENTERSUB_DB;
if (proto) {
switch (*proto) {
case '\0':
case ';':
optional = 1;
proto++;
continue;
case '$':
proto++;
arg++;
break;
case '%':
case '@':
arg++;
break;
case '&':
proto++;
arg++;
break;
case '*':
/* '*' allows any scalar type, including bareword */
proto++;
arg++;
goto wrapref; /* autoconvert GLOB -> GLOBref */
/* accidental subroutine, revert to bareword */
if (gvop) {
;
if (gvop &&
{
}
}
}
}
break;
case '[': case ']':
goto oops;
break;
case '\\':
proto++;
arg++;
switch (*proto++) {
case '[':
if (contextclass++ == 0) {
if (!e || e == proto)
goto oops;
}
else
goto oops;
goto again;
break;
case ']':
if (contextclass) {
char *p = proto;
char s = *p;
contextclass = 0;
*p = '\0';
while (*--p != '[');
*proto = s;
} else
goto oops;
break;
case '*':
goto wrapref;
if (!contextclass)
break;
case '&':
goto wrapref;
if (!contextclass)
break;
case '$':
goto wrapref;
if (!contextclass)
break;
case '@':
goto wrapref;
if (!contextclass)
break;
case '%':
goto wrapref;
if (!contextclass)
break;
{
kid->op_sibling = 0;
}
if (contextclass && e) {
proto = e + 1;
contextclass = 0;
}
break;
default: goto oops;
}
if (contextclass)
goto again;
break;
case ' ':
proto++;
continue;
default:
oops:
}
}
else
}
return o;
}
OP *
{
return o;
}
OP *
{
{
o->op_flags |= OPf_SPECIAL;
}
}
return ck_fun(o);
}
OP *
{
o = ck_fun(o);
if (kid)
}
return o;
}
/* A peephole optimizer. We visit the ops in the order they're to execute. */
void
{
if (!o || o->op_seq)
return;
SAVEOP();
for (; o; o = o->op_next) {
if (o->op_seq)
break;
/* The special value -1 is used by the B::C compiler backend to indicate
* that an op is statically defined and should not be freed */
PL_op_seqmax = 1;
PL_op = o;
switch (o->op_type) {
case OP_SETSTATE:
case OP_NEXTSTATE:
case OP_DBSTATE:
o->op_seq = PL_op_seqmax++;
break;
case OP_CONST:
#ifdef USE_ITHREADS
case OP_METHOD_NAMED:
/* Relocate sv to the pad for thread safety.
* Despite being a "constant", the SV is written to,
* for reference counts, sv_upgrade() etc. */
/* If op_sv is already a PADTMP then it is being used by
* some pad, so make a copy. */
}
else {
/* XXX I don't know how this isn't readonly already. */
}
}
#endif
o->op_seq = PL_op_seqmax++;
break;
case OP_CONCAT:
goto ignore_optimization;
else {
/* assert(PL_opargs[o->op_type] & OA_TARGLEX); */
o->op_private |= OPpTARGET_MY;
}
}
}
o->op_seq = PL_op_seqmax++;
break;
case OP_STUB:
o->op_seq = PL_op_seqmax++;
break; /* Scalar stub must produce undef. List stub is noop */
}
goto nothin;
case OP_NULL:
if (o->op_targ == OP_NEXTSTATE
|| o->op_targ == OP_DBSTATE
|| o->op_targ == OP_SETSTATE)
{
}
/* XXX: We avoid setting op_seq here to prevent later calls
to peep() from mistakenly concluding that optimisation
has already occurred. This doesn't fix the real problem,
though (See 20010220.007). AMS 20010719 */
continue;
}
break;
case OP_SCALAR:
case OP_LINESEQ:
case OP_SCOPE:
continue;
}
o->op_seq = PL_op_seqmax++;
break;
case OP_PADAV:
case OP_GV:
IV i;
<= 255 &&
i >= 0)
{
o->op_private = (U8)i;
}
else
o->op_flags |= OPf_SPECIAL;
o->op_type = OP_AELEMFAST;
}
o->op_seq = PL_op_seqmax++;
break;
}
| OPpOUR_INTRO);
}
}
/* XXX could check prototype here instead of just carping */
sv);
}
}
{
/* Turn "$a .= <FH>" into an OP_RCATLINE. AMS 20010917 */
o->op_type = OP_RCATLINE;
o->op_flags |= OPf_STACKED;
}
o->op_seq = PL_op_seqmax++;
break;
case OP_MAPWHILE:
case OP_GREPWHILE:
case OP_AND:
case OP_OR:
case OP_ANDASSIGN:
case OP_ORASSIGN:
case OP_COND_EXPR:
case OP_RANGE:
o->op_seq = PL_op_seqmax++;
break;
case OP_ENTERLOOP:
case OP_ENTERITER:
o->op_seq = PL_op_seqmax++;
break;
case OP_QR:
case OP_MATCH:
case OP_SUBST:
o->op_seq = PL_op_seqmax++;
while (cPMOP->op_pmreplstart &&
break;
case OP_EXEC:
o->op_seq = PL_op_seqmax++;
if (o->op_next->op_sibling &&
"Statement unlikely to be reached");
"\t(Maybe you meant system() when you said exec()?)\n");
}
}
break;
case OP_HELEM: {
o->op_seq = PL_op_seqmax++;
break;
/* Make the CONST have a shared SV */
0);
}
if ((o->op_private & (OPpLVAL_INTRO)))
break;
break;
break;
break;
if (!indsvp) {
}
if (ind < 1)
if (SvREADONLY(*svp))
SvREFCNT_dec(*svp);
break;
}
case OP_HSLICE: {
char *key;
o->op_seq = PL_op_seqmax++;
if ((o->op_private & (OPpLVAL_INTRO))
/* I bet there's always a pushmark... */
/* hmmm, no optimization if list contains only one key. */
break;
break;
break;
break;
/* Again guessing that the pushmark can be jumped over.... */
->op_first->op_sibling;
/* Check that the key list contains only constants. */
break;
if (key_op)
break;
if (!indsvp) {
"in variable %s of type %s",
}
if (ind < 1)
if (SvREADONLY(*svp))
SvREFCNT_dec(*svp);
}
break;
}
case OP_SORT: {
/* make @a = sort @a act in-place */
o->op_seq = PL_op_seqmax++;
/* check that RHS of sort is a single plain array */
break;
if (!oright)
break;
}
if (!oright ||
)
break;
/* o2 follows the chain of op_nexts through the LHS of the
* assign (if any) to the aassign op itself */
break;
break;
if (!o2
)
break;
break;
break;
/* check that the sort is the first arg on RHS of assign */
break;
break;
if (o2->op_sibling != o)
break;
/* check the array is the same on both sides */
)
break;
}
)
break;
/* transfer MODishness etc from LHS arg to RHS arg */
o->op_private |= OPpSORT_INPLACE;
/* excise push->gv->rv2av->null->aassign */
}
break;
}
default:
o->op_seq = PL_op_seqmax++;
break;
}
oldop = o;
}
}
{
if (!PL_custom_op_names) /* This probably shouldn't happen */
return PL_op_name[OP_CUSTOM];
if (!he)
}
{
if (!PL_custom_op_descs)
return PL_op_desc[OP_CUSTOM];
if (!he)
return PL_op_desc[OP_CUSTOM];
}
#include "XSUB.h"
/* Efficient sub that returns a constant scalar value. */
static void
{
if (items != 0) {
#if 0
#endif
}
XSRETURN(1);
}