This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Provide the names of the magic vtables in PL_magic_vtable_names[].
authorNicholas Clark <nick@ccl4.org>
Sat, 14 May 2011 11:26:37 +0000 (12:26 +0100)
committerNicholas Clark <nick@ccl4.org>
Sat, 11 Jun 2011 08:39:58 +0000 (10:39 +0200)
As it's a 1 to 1 mapping with the vtables in PL_magic_vtables[], refactor
Perl_do_magic_dump() to index into it directly to find the name for an
arbitrary mg_virtual, avoiding a long switch statement.

dump.c
globvar.sym
mg_vtable.h
regen/mg_vtable.pl

diff --git a/dump.c b/dump.c
index 97505fb..8165a7a 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -1290,39 +1290,11 @@ Perl_do_magic_dump(pTHX_ I32 level, PerlIO *file, const MAGIC *mg, I32 nest, I32
                         "  MAGIC = 0x%"UVxf"\n", PTR2UV(mg));
        if (mg->mg_virtual) {
             const MGVTBL * const v = mg->mg_virtual;
-           const char *s;
-           if      (v == &PL_vtbl_sv)         s = "sv";
-            else if (v == &PL_vtbl_env)        s = "env";
-            else if (v == &PL_vtbl_envelem)    s = "envelem";
-#ifndef PERL_MICRO
-            else if (v == &PL_vtbl_sigelem)    s = "sigelem";
-#endif
-            else if (v == &PL_vtbl_pack)       s = "pack";
-            else if (v == &PL_vtbl_packelem)   s = "packelem";
-            else if (v == &PL_vtbl_dbline)     s = "dbline";
-            else if (v == &PL_vtbl_isa)        s = "isa";
-            else if (v == &PL_vtbl_arylen)     s = "arylen";
-            else if (v == &PL_vtbl_mglob)      s = "mglob";
-            else if (v == &PL_vtbl_nkeys)      s = "nkeys";
-            else if (v == &PL_vtbl_taint)      s = "taint";
-            else if (v == &PL_vtbl_substr)     s = "substr";
-            else if (v == &PL_vtbl_vec)        s = "vec";
-            else if (v == &PL_vtbl_pos)        s = "pos";
-            else if (v == &PL_vtbl_uvar)       s = "uvar";
-            else if (v == &PL_vtbl_defelem)    s = "defelem";
-#ifdef USE_LOCALE_COLLATE
-           else if (v == &PL_vtbl_collxfrm)   s = "collxfrm";
-#endif
-           else if (v == &PL_vtbl_amagic)     s = "amagic";
-           else if (v == &PL_vtbl_amagicelem) s = "amagicelem";
-           else if (v == &PL_vtbl_backref)    s = "backref";
-           else if (v == &PL_vtbl_utf8)       s = "utf8";
-            else if (v == &PL_vtbl_arylen_p)   s = "arylen_p";
-            else if (v == &PL_vtbl_hintselem)  s = "hintselem";
-            else if (v == &PL_vtbl_hints)      s = "hints";
-           else                               s = NULL;
-           if (s)
-               Perl_dump_indent(aTHX_ level, file, "    MG_VIRTUAL = &PL_vtbl_%s\n", s);
+           if (v >= PL_magic_vtables
+               && v < PL_magic_vtables + magic_vtable_max) {
+               const U32 i = v - PL_magic_vtables;
+               Perl_dump_indent(aTHX_ level, file, "    MG_VIRTUAL = &PL_vtbl_%s\n", PL_magic_vtable_names[i]);
+           }
            else
                Perl_dump_indent(aTHX_ level, file, "    MG_VIRTUAL = 0x%"UVxf"\n", PTR2UV(v));
         }
index bb34973..49c2abf 100644 (file)
@@ -14,6 +14,7 @@ fold_locale
 freq
 keyword_plugin
 magic_vtables
+magic_vtable_names
 memory_wrap
 no_aelem
 no_dir_func
index 52937d7..516d2c9 100644 (file)
@@ -40,6 +40,43 @@ enum {               /* pass one of these to get_vtbl */
     magic_vtable_max
 };
 
+#ifdef DOINIT
+EXTCONST char *PL_magic_vtable_names[magic_vtable_max] = {
+    "sv",
+    "env",
+    "envelem",
+    "sigelem",
+    "pack",
+    "packelem",
+    "dbline",
+    "isa",
+    "isaelem",
+    "arylen",
+    "arylen_p",
+    "mglob",
+    "nkeys",
+    "taint",
+    "substr",
+    "vec",
+    "pos",
+    "uvar",
+    "defelem",
+    "regexp",
+    "regdata",
+    "regdatum",
+    "amagic",
+    "amagicelem",
+    "backref",
+    "ovrld",
+    "utf8",
+    "collxfrm",
+    "hintselem",
+    "hints"
+};
+#else
+EXTCONST char *PL_magic_vtable_names[magic_vtable_max];
+#endif
+
 /* These all need to be 0, not NULL, as NULL can be (void*)0, which is a
  * pointer to data, whereas we're assigning pointers to functions, which are
  * not the same beast. ANSI doesn't allow the assignment from one to the other.
index 0e78029..f527a3e 100644 (file)
@@ -60,13 +60,22 @@ my $h = open_new('mg_vtable.h', '>',
                   style => '*' });
 
 {
-    my @names = map {"want_vtbl_$_"} grep {!ref $_} @sig;
-    push @names, 'magic_vtable_max';
-    local $" = ",\n    ";
+    my @names = grep {!ref $_} @sig;
+    my $want = join ",\n    ", (map {"want_vtbl_$_"} @names), 'magic_vtable_max';
+    my $names = join qq{",\n    "}, @names;
+
     print $h <<"EOH";
 enum {         /* pass one of these to get_vtbl */
-    @names
+    $want
+};
+
+#ifdef DOINIT
+EXTCONST char *PL_magic_vtable_names[magic_vtable_max] = {
+    "$names"
 };
+#else
+EXTCONST char *PL_magic_vtable_names[magic_vtable_max];
+#endif
 
 EOH
 }