apply magic properly when initializing globs
[gitmo/Package-Stash-XS.git] / XS.xs
diff --git a/XS.xs b/XS.xs
index bfc23a2..59f6b79 100644 (file)
--- a/XS.xs
+++ b/XS.xs
         GvASSUMECV_on(g);               \
     }                                   \
     GvCVGEN(g) = 0;                     \
-    mro_method_changed_in(GvSTASH(g));  \
+    if (HvENAME_get(GvSTASH(g)))        \
+        mro_method_changed_in(GvSTASH(g)); \
 } while (0)
 #define GvSetIO(g,v) do {               \
     SvREFCNT_dec(GvIO(g));              \
@@ -324,6 +325,40 @@ static SV *_get_name(SV *self)
     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)
 {
     HV *namespace;
@@ -338,12 +373,8 @@ static void _expand_glob(SV *self, SV *varname)
             croak("_expand_glob called on stash slot with expanded glob");
         }
         else {
-            char *varname_pv;
-            STRLEN varname_len;
-
-            varname_pv = SvPV(varname, varname_len);
-            gv_init(glob, namespace, varname_pv, varname_len, 1);
             SvREFCNT_inc(glob);
+            _real_gv_init(glob, namespace, varname);
             if (!hv_store_ent(namespace, varname, (SV*)glob, 0)) {
                 croak("hv_store failed");
             }
@@ -582,11 +613,8 @@ add_symbol(self, variable, initial=NULL, ...)
         glob = (GV*)HeVAL(entry);
     }
     else {
-        char *varname_pv;
-        STRLEN varname_len;
         glob = (GV*)newSV(0);
-        varname_pv = SvPV(variable.name, varname_len);
-        gv_init(glob, namespace, varname_pv, varname_len, 1);
+        _real_gv_init(glob, namespace, variable.name);
         if (!hv_store_ent(namespace, variable.name, (SV*)glob, 0)) {
             croak("hv_store failed");
         }