Perl_dump_indent(aTHX_ level, file, "GV = NULL\n");
break;
case OP_CONST:
+ case OP_METHOD_NAMED:
Perl_dump_indent(aTHX_ level, file, "SV = %s\n", SvPEEK(cSVOPo->op_sv));
break;
case OP_SETSTATE:
#endif
#if defined(PERL_IN_PP_HOT_C) || defined(PERL_DECL_PROT)
#define get_db_sub S_get_db_sub
+#define method_common S_method_common
#endif
#if defined(PERL_IN_PP_SYS_C) || defined(PERL_DECL_PROT)
#define doform S_doform
#define ck_lfun Perl_ck_lfun
#define ck_listiob Perl_ck_listiob
#define ck_match Perl_ck_match
+#define ck_method Perl_ck_method
#define ck_null Perl_ck_null
#define ck_repeat Perl_ck_repeat
#define ck_require Perl_ck_require
#define pp_mapwhile Perl_pp_mapwhile
#define pp_match Perl_pp_match
#define pp_method Perl_pp_method
+#define pp_method_named Perl_pp_method_named
#define pp_mkdir Perl_pp_mkdir
#define pp_modulo Perl_pp_modulo
#define pp_msgctl Perl_pp_msgctl
#endif
#if defined(PERL_IN_PP_HOT_C) || defined(PERL_DECL_PROT)
#define get_db_sub(a,b) S_get_db_sub(aTHX_ a,b)
+#define method_common(a,b) S_method_common(aTHX_ a,b)
#endif
#if defined(PERL_IN_PP_SYS_C) || defined(PERL_DECL_PROT)
#define doform(a,b,c) S_doform(aTHX_ a,b,c)
#define ck_lfun(a) Perl_ck_lfun(aTHX_ a)
#define ck_listiob(a) Perl_ck_listiob(aTHX_ a)
#define ck_match(a) Perl_ck_match(aTHX_ a)
+#define ck_method(a) Perl_ck_method(aTHX_ a)
#define ck_null(a) Perl_ck_null(aTHX_ a)
#define ck_repeat(a) Perl_ck_repeat(aTHX_ a)
#define ck_require(a) Perl_ck_require(aTHX_ a)
#define pp_mapwhile() Perl_pp_mapwhile(aTHX)
#define pp_match() Perl_pp_match(aTHX)
#define pp_method() Perl_pp_method(aTHX)
+#define pp_method_named() Perl_pp_method_named(aTHX)
#define pp_mkdir() Perl_pp_mkdir(aTHX)
#define pp_modulo() Perl_pp_modulo(aTHX)
#define pp_msgctl() Perl_pp_msgctl(aTHX)
#if defined(PERL_IN_PP_HOT_C) || defined(PERL_DECL_PROT)
#define S_get_db_sub CPerlObj::S_get_db_sub
#define get_db_sub S_get_db_sub
+#define S_method_common CPerlObj::S_method_common
+#define method_common S_method_common
#endif
#if defined(PERL_IN_PP_SYS_C) || defined(PERL_DECL_PROT)
#define S_doform CPerlObj::S_doform
#define ck_listiob Perl_ck_listiob
#define Perl_ck_match CPerlObj::Perl_ck_match
#define ck_match Perl_ck_match
+#define Perl_ck_method CPerlObj::Perl_ck_method
+#define ck_method Perl_ck_method
#define Perl_ck_null CPerlObj::Perl_ck_null
#define ck_null Perl_ck_null
#define Perl_ck_repeat CPerlObj::Perl_ck_repeat
#define pp_match Perl_pp_match
#define Perl_pp_method CPerlObj::Perl_pp_method
#define pp_method Perl_pp_method
+#define Perl_pp_method_named CPerlObj::Perl_pp_method_named
+#define pp_method_named Perl_pp_method_named
#define Perl_pp_mkdir CPerlObj::Perl_pp_mkdir
#define pp_mkdir Perl_pp_mkdir
#define Perl_pp_modulo CPerlObj::Perl_pp_modulo
#if defined(PERL_IN_PP_HOT_C) || defined(PERL_DECL_PROT)
s |CV* |get_db_sub |SV **svp|CV *cv
+s |SV* |method_common |SV* meth|U32* hashp
#endif
#if defined(PERL_IN_PP_SYS_C) || defined(PERL_DECL_PROT)
rv2cv anoncode prototype
- entersub leavesub return method -- XXX loops via recursion?
+ entersub leavesub return method method_named -- XXX loops via recursion?
leaveeval -- needed for Safe to operate, is safe without entereval
#define Perl_ck_match pPerl->Perl_ck_match
#undef ck_match
#define ck_match Perl_ck_match
+#undef Perl_ck_method
+#define Perl_ck_method pPerl->Perl_ck_method
+#undef ck_method
+#define ck_method Perl_ck_method
#undef Perl_ck_null
#define Perl_ck_null pPerl->Perl_ck_null
#undef ck_null
#define Perl_pp_method pPerl->Perl_pp_method
#undef pp_method
#define pp_method Perl_pp_method
+#undef Perl_pp_method_named
+#define Perl_pp_method_named pPerl->Perl_pp_method_named
+#undef pp_method_named
+#define pp_method_named Perl_pp_method_named
#undef Perl_pp_mkdir
#define Perl_pp_mkdir pPerl->Perl_pp_mkdir
#undef pp_mkdir
}
else {
OP *pack;
- OP *meth;
if (version->op_type != OP_CONST || !SvNIOK(vesv))
Perl_croak(aTHX_ "Version number must be constant number");
pack = newSVOP(OP_CONST, 0, newSVsv(((SVOP*)id)->op_sv));
/* Fake up a method call to VERSION */
- meth = newSVOP(OP_CONST, 0, newSVpvn("VERSION", 7));
veop = convert(OP_ENTERSUB, OPf_STACKED|OPf_SPECIAL,
append_elem(OP_LIST,
prepend_elem(OP_LIST, pack, list(version)),
- newUNOP(OP_METHOD, 0, meth)));
+ newSVOP(OP_METHOD_NAMED, 0,
+ newSVpvn("VERSION", 7))));
}
}
else {
/* Make copy of id so we don't free it twice */
pack = newSVOP(OP_CONST, 0, newSVsv(((SVOP*)id)->op_sv));
- meth = newSVOP(OP_CONST, 0,
- aver
- ? newSVpvn("import", 6)
- : newSVpvn("unimport", 8)
- );
imop = convert(OP_ENTERSUB, OPf_STACKED|OPf_SPECIAL,
append_elem(OP_LIST,
prepend_elem(OP_LIST, pack, list(arg)),
- newUNOP(OP_METHOD, 0, meth)));
+ newSVOP(OP_METHOD_NAMED, 0,
+ aver ? newSVpvn("import", 6)
+ : newSVpvn("unimport", 8))));
}
/* Fake up a require, handle override, if any */
}
OP *
+Perl_ck_method(pTHX_ OP *o)
+{
+ OP *kid = cUNOPo->op_first;
+ if (kid->op_type == OP_CONST) {
+ SV* sv = kSVOP->op_sv;
+ if (!(strchr(SvPVX(sv), ':') || strchr(SvPVX(sv), '\''))) {
+ OP *cmop;
+ sv_upgrade(sv, SVt_PVIV);
+ SvIOK_on(sv);
+ PERL_HASH(SvUVX(sv), SvPVX(sv), SvCUR(sv));
+ cmop = newSVOP(OP_METHOD_NAMED, 0, sv);
+ kSVOP->op_sv = Nullsv;
+ op_free(o);
+ return cmop;
+ }
+ }
+ return o;
+}
+
+OP *
Perl_ck_null(pTHX_ OP *o)
{
return o;
}
}
}
- else if (cvop->op_type == OP_METHOD) {
+ else if (cvop->op_type == OP_METHOD || cvop->op_type == OP_METHOD_NAMED) {
if (o2->op_type == OP_CONST)
o2->op_private &= ~OPpCONST_STRICT;
else if (o2->op_type == OP_LIST) {
OP_LOCK, /* 346 */
OP_THREADSV, /* 347 */
OP_SETSTATE, /* 348 */
+ OP_METHOD_NAMED,/* 349 */
OP_max
} opcode;
-#define MAXO 349
+#define MAXO 350
START_EXTERN_C
"lock",
"threadsv",
"setstate",
+ "method_named",
};
#endif
"lock",
"per-thread variable",
"set statement info",
+ "method with known name",
};
#endif
Perl_pp_lock,
Perl_pp_threadsv,
Perl_pp_setstate,
+ Perl_pp_method_named,
};
#endif
Perl_ck_null, /* cond_expr */
Perl_ck_null, /* andassign */
Perl_ck_null, /* orassign */
- Perl_ck_null, /* method */
+ Perl_ck_method, /* method */
Perl_ck_subr, /* entersub */
Perl_ck_null, /* leavesub */
Perl_ck_fun, /* caller */
Perl_ck_rfun, /* lock */
Perl_ck_null, /* threadsv */
Perl_ck_null, /* setstate */
+ Perl_ck_null, /* method_named */
};
#endif
0x00003604, /* lock */
0x00000044, /* threadsv */
0x00001404, /* setstate */
+ 0x00000c40, /* method_named */
};
#endif
andassign logical and assignment ck_null s|
orassign logical or assignment ck_null s|
-method method lookup ck_null d1
+method method lookup ck_method d1
entersub subroutine entry ck_subr dmt1 L
leavesub subroutine exit ck_null 1
caller caller ck_fun t% S?
# Control (contd.)
setstate set statement info ck_null s;
+method_named method with known name ck_null d$
return ((CPerlObj*)pPerl)->Perl_ck_match(o);
}
+#undef Perl_ck_method
+OP *
+Perl_ck_method(pTHXo_ OP *o)
+{
+ return ((CPerlObj*)pPerl)->Perl_ck_method(o);
+}
+
#undef Perl_ck_null
OP *
Perl_ck_null(pTHXo_ OP *o)
return ((CPerlObj*)pPerl)->Perl_pp_method();
}
+#undef Perl_pp_method_named
+OP *
+Perl_pp_method_named(pTHXo)
+{
+ return ((CPerlObj*)pPerl)->Perl_pp_method_named();
+}
+
#undef Perl_pp_mkdir
OP *
Perl_pp_mkdir(pTHXo)
Perl_ck_lfun
Perl_ck_listiob
Perl_ck_match
+Perl_ck_method
Perl_ck_null
Perl_ck_repeat
Perl_ck_require
Perl_pp_lock
Perl_pp_threadsv
Perl_pp_setstate
+Perl_pp_method_named
PP(pp_method)
{
djSP;
+ SV* sv = TOPs;
+
+ if (SvROK(sv)) {
+ SV* rsv = SvRV(rsv);
+ if (SvTYPE(rsv) == SVt_PVCV) {
+ SETs(rsv);
+ RETURN;
+ }
+ }
+
+ SETs(method_common(sv, Null(U32*)));
+ RETURN;
+}
+
+PP(pp_method_named)
+{
+ djSP;
+ SV* sv = cSVOP->op_sv;
+ U32 hash = SvUVX(sv);
+
+ XPUSHs(method_common(sv, &hash));
+ RETURN;
+}
+
+STATIC SV *
+S_method_common(pTHX_ SV* meth, U32* hashp)
+{
+ djSP;
SV* sv;
SV* ob;
GV* gv;
HV* stash;
char* name;
+ STRLEN namelen;
char* packname;
STRLEN packlen;
- if (SvROK(TOPs)) {
- sv = SvRV(TOPs);
- if (SvTYPE(sv) == SVt_PVCV) {
- SETs(sv);
- RETURN;
- }
- }
-
- name = SvPV(TOPs, packlen);
+ name = SvPV(meth, namelen);
sv = *(PL_stack_base + TOPMARK + 1);
-
+
if (SvGMAGICAL(sv))
mg_get(sv);
if (SvROK(sv))
: !isIDFIRST(*packname)
))
{
- DIE(aTHX_ "Can't call method \"%s\" %s", name,
- SvOK(sv)? "without a package or object reference"
- : "on an undefined value");
+ Perl_croak(aTHX_ "Can't call method \"%s\" %s", name,
+ SvOK(sv) ? "without a package or object reference"
+ : "on an undefined value");
}
stash = gv_stashpvn(packname, packlen, TRUE);
goto fetch;
}
if (!ob || !SvOBJECT(ob))
- DIE(aTHX_ "Can't call method \"%s\" on unblessed reference", name);
+ Perl_croak(aTHX_ "Can't call method \"%s\" on unblessed reference",
+ name);
stash = SvSTASH(ob);
fetch:
+ /* shortcut for simple names */
+ if (hashp) {
+ HE* he = hv_fetch_ent(stash, meth, 0, *hashp);
+ if (he) {
+ gv = (GV*)HeVAL(he);
+ if (isGV(gv) && GvCV(gv) &&
+ (!GvCVGEN(gv) || GvCVGEN(gv) == PL_sub_generation))
+ return (SV*)GvCV(gv);
+ }
+ }
+
gv = gv_fetchmethod(stash, name);
if (!gv) {
char* leaf = name;
packname = name;
packlen = sep - name;
}
- DIE(aTHX_ "Can't locate object method \"%s\" via package \"%.*s\"",
- leaf, (int)packlen, packname);
+ Perl_croak(aTHX_
+ "Can't locate object method \"%s\" via package \"%s\"",
+ leaf, packname);
}
- SETs(isGV(gv) ? (SV*)GvCV(gv) : (SV*)gv);
- RETURN;
+ return isGV(gv) ? (SV*)GvCV(gv) : (SV*)gv;
}
#ifdef USE_THREADS
PERL_CKDEF(Perl_ck_lfun)
PERL_CKDEF(Perl_ck_listiob)
PERL_CKDEF(Perl_ck_match)
+PERL_CKDEF(Perl_ck_method)
PERL_CKDEF(Perl_ck_null)
PERL_CKDEF(Perl_ck_repeat)
PERL_CKDEF(Perl_ck_require)
PERL_PPDEF(Perl_pp_lock)
PERL_PPDEF(Perl_pp_threadsv)
PERL_PPDEF(Perl_pp_setstate)
+PERL_PPDEF(Perl_pp_method_named)
#endif
#if defined(PERL_IN_PP_HOT_C) || defined(PERL_DECL_PROT)
STATIC CV* S_get_db_sub(pTHX_ SV **svp, CV *cv);
+STATIC SV* S_method_common(pTHX_ SV* meth, U32* hashp);
#endif
#if defined(PERL_IN_PP_SYS_C) || defined(PERL_DECL_PROT)
STATIC OP* S_doform(pTHX_ CV *cv, GV *gv, OP *retop);