summaryrefslogtreecommitdiff
path: root/pp_hot.c
diff options
context:
space:
mode:
authorChip Salzenberg <chip@perl.com>1997-04-17 00:00:00 +0000
committerChip Salzenberg <chip@atlantic.net>1997-04-17 00:00:00 +0000
commitac91690fe10ac7691f6f40c5d55578b8254e3705 (patch)
tree74b4943b53b49e76e2286b69c0c59ec95a20315b /pp_hot.c
parent137443ea0a858c43f5a720730cac6209a7d41948 (diff)
downloadperl-ac91690fe10ac7691f6f40c5d55578b8254e3705.tar.gz
Fix error messages on method lookup failure
Diffstat (limited to 'pp_hot.c')
-rw-r--r--pp_hot.c93
1 files changed, 56 insertions, 37 deletions
diff --git a/pp_hot.c b/pp_hot.c
index 97f9c752f2..7d0e91a103 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -2064,61 +2064,80 @@ PP(pp_method)
dSP;
SV* sv;
SV* ob;
+ HV* stash;
GV* gv;
- SV* nm;
+ char* packname;
+ STRLEN packlen;
+ char* name;
+ char* origname;
+ char* sep;
+ char* p;
- nm = TOPs;
sv = *(stack_base + TOPMARK + 1);
-
- gv = 0;
+
+ sep = name = origname = SvPV(TOPs, na);
+ for (p = name; *p; p++) {
+ if (*p == '\'')
+ sep = p, name = p + 1;
+ else if (*p == ':' && *(p + 1) == ':')
+ sep = p, name = p + 2;
+ }
+ if (name == origname)
+ packname = Nullch;
+ else {
+ packname = origname;
+ packlen = sep - origname;
+
+ /* let gv_fetchmethod() handle SUPER:: */
+ if (packlen == 5 && strnEQ(packname, "SUPER", 5)) {
+ packname = Nullch;
+ name = origname;
+ }
+ }
+
if (SvGMAGICAL(sv))
mg_get(sv);
if (SvROK(sv))
ob = (SV*)SvRV(sv);
else {
+ char* tname = Nullch;
+ STRLEN tlen = 0;
GV* iogv;
- char* packname = 0;
- STRLEN packlen;
if (!SvOK(sv) ||
- !(packname = SvPV(sv, packlen)) ||
- !(iogv = gv_fetchpv(packname, FALSE, SVt_PVIO)) ||
- !(ob=(SV*)GvIO(iogv)))
+ !(tname = SvPV(sv, tlen)) ||
+ !(iogv = gv_fetchpv(tname, FALSE, SVt_PVIO)) ||
+ !(ob = (SV*)GvIO(iogv)))
{
- char *name = SvPV(nm, na);
- HV *stash;
- if (!packname || !isALPHA(*packname))
-DIE("Can't call method \"%s\" without a package or object reference", name);
- if (!(stash = gv_stashpvn(packname, packlen, FALSE))) {
- if (gv_stashpvn("UNIVERSAL", 9, FALSE))
- stash = gv_stashpvn(packname, packlen, TRUE);
- else
- DIE("Can't call method \"%s\" in empty package \"%s\"",
- name, packname);
+ if (!packname) {
+ packname = tname;
+ packlen = tlen;
}
- gv = gv_fetchmethod(stash,name);
- if (!gv)
- DIE("Can't locate object method \"%s\" via package \"%s\"",
- name, packname);
- SETs(isGV(gv) ? (SV*)GvCV(gv) : (SV*)gv);
- RETURN;
+ if (!packname || !isALPHA(*packname))
+ DIE("Can't call method \"%s\" without a package or object reference", name);
+ goto fetch;
}
- *(stack_base + TOPMARK + 1) = sv_2mortal(newRV((SV*)iogv));
- }
- if (!ob || !SvOBJECT(ob)) {
- char *name = SvPV(nm, na);
- DIE("Can't call method \"%s\" on unblessed reference", name);
+ /* working on an IO object */
+ *(stack_base + TOPMARK + 1) = sv_2mortal(newRV((SV*)iogv));
}
- if (!gv) { /* nothing cached */
- char *name = SvPV(nm, na);
- gv = gv_fetchmethod(SvSTASH(ob),name);
- if (!gv)
- DIE("Can't locate object method \"%s\" via package \"%s\"",
- name, HvNAME(SvSTASH(ob)));
- }
+ if (!ob || !SvOBJECT(ob))
+ DIE("Can't call method \"%s\" on unblessed reference", origname);
+ if (!packname)
+ stash = SvSTASH(ob);
+ else {
+ fetch:
+ stash = gv_stashpvn(packname, packlen, TRUE);
+ }
+ gv = gv_fetchmethod(stash, name);
+ if (!gv)
+ DIE("Can't locate object method \"%s\" via package \"%s\"",
+ name, HvNAME((strnEQ(name, "SUPER", 5) &&
+ (name[5] == '\'' ||
+ (name[5] == ':' && name[6] == ':')))
+ ? curcop->cop_stash : stash));
SETs(isGV(gv) ? (SV*)GvCV(gv) : (SV*)gv);
RETURN;
}