#define GvCV_set(gv, cv) (GvCV(gv) = (CV*)(cv))
#endif
+#ifndef MUTABLE_PTR
+#define MUTABLE_PTR(p) ((void *) (p))
+#endif
+
+#ifndef MUTABLE_SV
+#define MUTABLE_SV(p) ((SV *)MUTABLE_PTR(p))
+#endif
+
#ifndef SVT_SCALAR
#define SVT_SCALAR(svt) (svt <= SVt_PVLV)
#endif
} while (0)
#define GvSetCV(g,v) do { \
SvREFCNT_dec(GvCV(g)); \
- if ((GvCV_set(g, v))) { \
+ if ((GvCV_set(g, (CV*)(v)))) { \
GvIMPORTED_CV_on(g); \
GvASSUMECV_on(g); \
} \
return ret;
}
+static void _real_gv_init(GV *gv, HV *stash, SV *name)
+{
+ char *name_pv;
+ STRLEN name_len;
+
+ name_pv = SvPV(name, name_len);
+ gv_init(gv, stash, name_pv, name_len, 1);
+
+ /* XXX: copied and pasted from gv_fetchpvn_flags and such */
+ /* ignoring the stuff for CORE:: and main:: for now, and also
+ * ignoring the GvMULTI_on bits, since we pass 1 to gv_init above */
+ switch (name_pv[0]) {
+ case 'I':
+ if (strEQ(&name_pv[1], "SA")) {
+ AV *av;
+
+ av = GvAVn(gv);
+ sv_magic(MUTABLE_SV(av), MUTABLE_SV(gv), PERL_MAGIC_isa,
+ NULL, 0);
+ }
+ break;
+ case 'O':
+ if (strEQ(&name_pv[1], "VERLOAD")) {
+ HV *hv;
+
+ hv = GvHVn(gv);
+ hv_magic(hv, NULL, PERL_MAGIC_overload);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
static void _expand_glob(SV *self, SV *varname)
{
- SV *name;
+ HV *namespace;
+ HE *entry;
+ GV *glob;
- name = newSVsv(_get_name(self));
- sv_catpvs(name, "::");
- sv_catsv(name, varname);
+ namespace = _get_namespace(self);
- /* can't use gv_init here, because it screws up @ISA in a way that I
- * can't reproduce, but that CMOP triggers */
- gv_fetchsv(name, GV_ADD, SVt_NULL);
- SvREFCNT_dec(name);
+ if (entry = hv_fetch_ent(namespace, varname, 0, 0)) {
+ glob = (GV*)HeVAL(entry);
+ if (isGV(glob)) {
+ croak("_expand_glob called on stash slot with expanded glob");
+ }
+ else {
+ SvREFCNT_inc(glob);
+ _real_gv_init(glob, namespace, varname);
+ if (!hv_store_ent(namespace, varname, (SV*)glob, 0)) {
+ croak("hv_store failed");
+ }
+ }
+ }
+ else {
+ croak("_expand_glob called on nonexistent stash slot");
+ }
}
static SV *_get_symbol(SV *self, varspec_t *variable, int vivify)
varspec_t variable
SV *initial
PREINIT:
- SV *name;
GV *glob;
+ HV *namespace;
+ HE *entry;
CODE:
if (initial && !_valid_for_type(initial, variable.type))
croak("%s is not of type %s",
SvPV_nolen(initial), vartype_to_string(variable.type));
- name = newSVsv(_get_name(self));
- sv_catpvs(name, "::");
- sv_catsv(name, variable.name);
-
if (items > 2 && (PL_perldb & 0x10) && variable.type == VAR_CODE) {
int i;
char *filename = NULL;
I32 first_line_num = -1, last_line_num = -1;
- SV *dbval;
+ SV *dbval, *name;
HV *dbsub;
if ((items - 3) % 2)
if (last_line_num == -1)
last_line_num = first_line_num;
+ name = newSVsv(_get_name(self));
+ sv_catpvs(name, "::");
+ sv_catsv(name, variable.name);
+
/* http://perldoc.perl.org/perldebguts.html#Debugger-Internals */
dbsub = get_hv("DB::sub", 1);
dbval = newSVpvf("%s:%d-%d", filename, first_line_num, last_line_num);
SvPV_nolen(name));
SvREFCNT_dec(dbval);
}
+
+ SvREFCNT_dec(name);
}
/* GV_ADDMULTI rather than GV_ADD because otherwise you get 'used only
* once' warnings in some situations... i can't reproduce this, but CMOP
* triggers it */
- glob = gv_fetchsv(name, GV_ADDMULTI, vartype_to_svtype(variable.type));
+ namespace = _get_namespace(self);
+ entry = hv_fetch_ent(namespace, variable.name, 0, 0);
+ if (entry) {
+ glob = (GV*)HeVAL(entry);
+ }
+ else {
+ glob = (GV*)newSV(0);
+ _real_gv_init(glob, namespace, variable.name);
+ if (!hv_store_ent(namespace, variable.name, (SV*)glob, 0)) {
+ croak("hv_store failed");
+ }
+ }
if (initial) {
SV *val;
}
}
- SvREFCNT_dec(name);
-
void
remove_glob(self, name)
SV *self