#define I_HAS_PERL(R, V, S) (PERL_REVISION > (R) || (PERL_REVISION == (R) && (PERL_VERSION > (V) || (PERL_VERSION == (V) && (PERL_SUBVERSION >= (S))))))
#if I_HAS_PERL(5, 10, 0) || defined(PL_parser)
-# ifndef PL_lex_inwhat
-# define PL_lex_inwhat PL_parser->lex_inwhat
-# endif
-# ifndef PL_linestr
-# define PL_linestr PL_parser->linestr
-# endif
# ifndef PL_bufptr
# define PL_bufptr PL_parser->bufptr
# endif
# define PL_oldbufptr PL_parser->oldbufptr
# endif
#else
-# ifndef PL_lex_inwhat
-# define PL_lex_inwhat PL_Ilex_inwhat
-# endif
-# ifndef PL_linestr
-# define PL_linestr PL_Ilinestr
-# endif
# ifndef PL_bufptr
# define PL_bufptr PL_Ibufptr
# endif
typedef struct {
#if I_THREADSAFE
- ptable *tbl; /* It really is a ptable_hints */
- tTHX owner;
+ ptable *tbl; /* It really is a ptable_hints */
+ tTHX owner;
#endif
- ptable *map;
- const char *linestr;
+ ptable *map;
} my_cxt_t;
START_MY_CXT
STRLEN len;
dMY_CXT;
- /* When lex_inwhat is set, we're in a quotelike environment (qq, qr, but not q)
- * In this case the linestr has temporarly changed, but the old buffer should
- * still be alive somewhere. */
-
- if (!PL_lex_inwhat) {
- const char *pl_linestr = SvPVX_const(PL_linestr);
- if (MY_CXT.linestr != pl_linestr) {
- ptable_clear(MY_CXT.map);
- MY_CXT.linestr = pl_linestr;
- }
- }
-
if (!(oi = ptable_fetch(MY_CXT.map, o))) {
Newx(oi, 1, indirect_op_info_t);
ptable_store(MY_CXT.map, o, oi);
#define indirect_map_fetch(O) indirect_map_fetch(aTHX_ (O))
dMY_CXT;
- if (MY_CXT.linestr != SvPVX_const(PL_linestr))
- return NULL;
-
return ptable_fetch(MY_CXT.map, o);
}
return o;
}
+/* ... ck_method_named ..................................................... */
+
+/* "use foo/no foo" compiles its call to import/unimport directly to a
+ * method_named op. */
+
+STATIC OP *(*indirect_old_ck_method_named)(pTHX_ OP *) = 0;
+
+STATIC OP *indirect_ck_method_named(pTHX_ OP *o) {
+ if (indirect_hint()) {
+ const char *s;
+ line_t line;
+ SV *sv;
+
+ sv = cSVOPo_sv;
+ if (!SvPOK(sv) || (SvTYPE(sv) < SVt_PV))
+ goto done;
+ sv = sv_mortalcopy(sv);
+ s = indirect_find(sv, PL_oldbufptr);
+ if (!s)
+ goto done;
+ line = CopLINE(&PL_compiling);
+
+ o = CALL_FPTR(indirect_old_ck_method_named)(aTHX_ o);
+
+ indirect_map_store(o, s, sv, line);
+ return o;
+ }
+
+done:
+ o = CALL_FPTR(indirect_old_ck_method_named)(aTHX_ o);
+
+ indirect_map_delete(o);
+ return o;
+}
+
/* ... ck_entersub ......................................................... */
STATIC int indirect_is_indirect(const indirect_op_info_t *moi, const indirect_op_info_t *ooi) {
ptable_hints_free(MY_CXT.tbl);
#endif
- PL_check[OP_CONST] = MEMBER_TO_FPTR(indirect_old_ck_const);
- indirect_old_ck_const = 0;
- PL_check[OP_RV2SV] = MEMBER_TO_FPTR(indirect_old_ck_rv2sv);
- indirect_old_ck_rv2sv = 0;
- PL_check[OP_PADANY] = MEMBER_TO_FPTR(indirect_old_ck_padany);
- indirect_old_ck_padany = 0;
- PL_check[OP_SCOPE] = MEMBER_TO_FPTR(indirect_old_ck_scope);
- indirect_old_ck_scope = 0;
- PL_check[OP_LINESEQ] = MEMBER_TO_FPTR(indirect_old_ck_lineseq);
- indirect_old_ck_lineseq = 0;
-
- PL_check[OP_METHOD] = MEMBER_TO_FPTR(indirect_old_ck_method);
- indirect_old_ck_method = 0;
- PL_check[OP_ENTERSUB] = MEMBER_TO_FPTR(indirect_old_ck_entersub);
- indirect_old_ck_entersub = 0;
+ PL_check[OP_CONST] = MEMBER_TO_FPTR(indirect_old_ck_const);
+ indirect_old_ck_const = 0;
+ PL_check[OP_RV2SV] = MEMBER_TO_FPTR(indirect_old_ck_rv2sv);
+ indirect_old_ck_rv2sv = 0;
+ PL_check[OP_PADANY] = MEMBER_TO_FPTR(indirect_old_ck_padany);
+ indirect_old_ck_padany = 0;
+ PL_check[OP_SCOPE] = MEMBER_TO_FPTR(indirect_old_ck_scope);
+ indirect_old_ck_scope = 0;
+ PL_check[OP_LINESEQ] = MEMBER_TO_FPTR(indirect_old_ck_lineseq);
+ indirect_old_ck_lineseq = 0;
+
+ PL_check[OP_METHOD] = MEMBER_TO_FPTR(indirect_old_ck_method);
+ indirect_old_ck_method = 0;
+ PL_check[OP_METHOD_NAMED] = MEMBER_TO_FPTR(indirect_old_ck_method_named);
+ indirect_old_ck_method_named = 0;
+ PL_check[OP_ENTERSUB] = MEMBER_TO_FPTR(indirect_old_ck_entersub);
+ indirect_old_ck_entersub = 0;
indirect_initialized = 0;
}
{
MY_CXT_INIT;
#if I_THREADSAFE
- MY_CXT.tbl = ptable_new();
- MY_CXT.owner = aTHX;
+ MY_CXT.tbl = ptable_new();
+ MY_CXT.owner = aTHX;
#endif
- MY_CXT.map = ptable_new();
- MY_CXT.linestr = NULL;
+ MY_CXT.map = ptable_new();
}
- indirect_old_ck_const = PL_check[OP_CONST];
- PL_check[OP_CONST] = MEMBER_TO_FPTR(indirect_ck_const);
- indirect_old_ck_rv2sv = PL_check[OP_RV2SV];
- PL_check[OP_RV2SV] = MEMBER_TO_FPTR(indirect_ck_rv2sv);
- indirect_old_ck_padany = PL_check[OP_PADANY];
- PL_check[OP_PADANY] = MEMBER_TO_FPTR(indirect_ck_padany);
- indirect_old_ck_scope = PL_check[OP_SCOPE];
- PL_check[OP_SCOPE] = MEMBER_TO_FPTR(indirect_ck_scope);
- indirect_old_ck_lineseq = PL_check[OP_LINESEQ];
- PL_check[OP_LINESEQ] = MEMBER_TO_FPTR(indirect_ck_scope);
-
- indirect_old_ck_method = PL_check[OP_METHOD];
- PL_check[OP_METHOD] = MEMBER_TO_FPTR(indirect_ck_method);
- indirect_old_ck_entersub = PL_check[OP_ENTERSUB];
- PL_check[OP_ENTERSUB] = MEMBER_TO_FPTR(indirect_ck_entersub);
+ indirect_old_ck_const = PL_check[OP_CONST];
+ PL_check[OP_CONST] = MEMBER_TO_FPTR(indirect_ck_const);
+ indirect_old_ck_rv2sv = PL_check[OP_RV2SV];
+ PL_check[OP_RV2SV] = MEMBER_TO_FPTR(indirect_ck_rv2sv);
+ indirect_old_ck_padany = PL_check[OP_PADANY];
+ PL_check[OP_PADANY] = MEMBER_TO_FPTR(indirect_ck_padany);
+ indirect_old_ck_scope = PL_check[OP_SCOPE];
+ PL_check[OP_SCOPE] = MEMBER_TO_FPTR(indirect_ck_scope);
+ indirect_old_ck_lineseq = PL_check[OP_LINESEQ];
+ PL_check[OP_LINESEQ] = MEMBER_TO_FPTR(indirect_ck_scope);
+
+ indirect_old_ck_method = PL_check[OP_METHOD];
+ PL_check[OP_METHOD] = MEMBER_TO_FPTR(indirect_ck_method);
+ indirect_old_ck_method_named = PL_check[OP_METHOD_NAMED];
+ PL_check[OP_METHOD_NAMED] = MEMBER_TO_FPTR(indirect_ck_method_named);
+ indirect_old_ck_entersub = PL_check[OP_ENTERSUB];
+ PL_check[OP_ENTERSUB] = MEMBER_TO_FPTR(indirect_ck_entersub);
#if I_MULTIPLICITY
call_atexit(indirect_teardown, aTHX);
}
{
MY_CXT_CLONE;
- MY_CXT.map = ptable_new();
- MY_CXT.linestr = NULL;
- MY_CXT.tbl = t;
- MY_CXT.owner = aTHX;
+ MY_CXT.map = ptable_new();
+ MY_CXT.tbl = t;
+ MY_CXT.owner = aTHX;
}
reap(3, indirect_thread_cleanup, NULL);
XSRETURN(0);