Refactor Perl_get_vtbl() to a small array lookup from a large switch statement.
authorNicholas Clark <nick@ccl4.org>
Fri, 13 May 2011 20:21:49 +0000 (21:21 +0100)
committerNicholas Clark <nick@ccl4.org>
Sat, 11 Jun 2011 08:12:19 +0000 (10:12 +0200)
Provide magic_vtable_max, the number of elements in PL_magic_vtables[].

mg_vtable.h
regen/mg_vtable.pl
util.c

index 21f2e7a..2db8f3f 100644 (file)
@@ -38,7 +38,8 @@ enum {                /* pass one of these to get_vtbl */
     want_vtbl_utf8,
     want_vtbl_collxfrm,
     want_vtbl_hintselem,
-    want_vtbl_hints
+    want_vtbl_hints,
+    magic_vtable_max
 };
 
 /* These all need to be 0, not NULL, as NULL can be (void*)0, which is a
@@ -59,7 +60,7 @@ enum {                /* pass one of these to get_vtbl */
 */
 
 #ifdef DOINIT
-EXT_MGVTBL PL_magic_vtables[] = {
+EXT_MGVTBL PL_magic_vtables[magic_vtable_max] = {
   { Perl_magic_get, Perl_magic_set, Perl_magic_len, 0, 0, 0, 0, 0 },
   { 0, Perl_magic_set_all_env, 0, Perl_magic_clear_all_env, 0, 0, 0, 0 },
   { 0, Perl_magic_setenv, 0, Perl_magic_clearenv, 0, 0, 0, 0 },
@@ -102,7 +103,7 @@ EXT_MGVTBL PL_magic_vtables[] = {
   { 0, 0, 0, Perl_magic_clearhints, 0, 0, 0, 0 }
 };
 #else
-EXT_MGVTBL PL_magic_vtables[];
+EXT_MGVTBL PL_magic_vtables[magic_vtable_max];
 #endif
 
 #define PL_vtbl_amagic PL_magic_vtables[want_vtbl_amagic]
index d09bfda..3419070 100644 (file)
@@ -63,6 +63,7 @@ my $h = open_new('mg_vtable.h', '>',
 
 {
     my @names = map {"want_vtbl_$_"} grep {!ref $_} @sig;
+    push @names, 'magic_vtable_max';
     local $" = ",\n    ";
     print $h <<"EOH";
 enum {         /* pass one of these to get_vtbl */
@@ -91,7 +92,7 @@ print $h <<'EOH';
 */
 
 #ifdef DOINIT
-EXT_MGVTBL PL_magic_vtables[] = {
+EXT_MGVTBL PL_magic_vtables[magic_vtable_max] = {
 EOH
 
 my @vtable_names;
@@ -120,7 +121,7 @@ EOH
 print $h <<'EOH';
 };
 #else
-EXT_MGVTBL PL_magic_vtables[];
+EXT_MGVTBL PL_magic_vtables[magic_vtable_max];
 #endif
 
 EOH
diff --git a/util.c b/util.c
index 7355d03..19fec65 100644 (file)
--- a/util.c
+++ b/util.c
@@ -3736,103 +3736,10 @@ Perl_getenv_len(pTHX_ const char *env_elem, unsigned long *len)
 MGVTBL*
 Perl_get_vtbl(pTHX_ int vtbl_id)
 {
-    const MGVTBL* result;
     PERL_UNUSED_CONTEXT;
 
-    switch(vtbl_id) {
-    case want_vtbl_sv:
-       result = &PL_vtbl_sv;
-       break;
-    case want_vtbl_env:
-       result = &PL_vtbl_env;
-       break;
-    case want_vtbl_envelem:
-       result = &PL_vtbl_envelem;
-       break;
-#ifndef PERL_MICRO
-    case want_vtbl_sigelem:
-       result = &PL_vtbl_sigelem;
-       break;
-#endif
-    case want_vtbl_pack:
-       result = &PL_vtbl_pack;
-       break;
-    case want_vtbl_packelem:
-       result = &PL_vtbl_packelem;
-       break;
-    case want_vtbl_dbline:
-       result = &PL_vtbl_dbline;
-       break;
-    case want_vtbl_isa:
-       result = &PL_vtbl_isa;
-       break;
-    case want_vtbl_isaelem:
-       result = &PL_vtbl_isaelem;
-       break;
-    case want_vtbl_arylen:
-       result = &PL_vtbl_arylen;
-       break;
-    case want_vtbl_mglob:
-       result = &PL_vtbl_mglob;
-       break;
-    case want_vtbl_nkeys:
-       result = &PL_vtbl_nkeys;
-       break;
-    case want_vtbl_taint:
-       result = &PL_vtbl_taint;
-       break;
-    case want_vtbl_substr:
-       result = &PL_vtbl_substr;
-       break;
-    case want_vtbl_vec:
-       result = &PL_vtbl_vec;
-       break;
-    case want_vtbl_pos:
-       result = &PL_vtbl_pos;
-       break;
-    case want_vtbl_bm:
-       result = &PL_vtbl_bm;
-       break;
-    case want_vtbl_fm:
-       result = &PL_vtbl_fm;
-       break;
-    case want_vtbl_uvar:
-       result = &PL_vtbl_uvar;
-       break;
-    case want_vtbl_defelem:
-       result = &PL_vtbl_defelem;
-       break;
-    case want_vtbl_regexp:
-       result = &PL_vtbl_regexp;
-       break;
-    case want_vtbl_regdata:
-       result = &PL_vtbl_regdata;
-       break;
-    case want_vtbl_regdatum:
-       result = &PL_vtbl_regdatum;
-       break;
-#ifdef USE_LOCALE_COLLATE
-    case want_vtbl_collxfrm:
-       result = &PL_vtbl_collxfrm;
-       break;
-#endif
-    case want_vtbl_amagic:
-       result = &PL_vtbl_amagic;
-       break;
-    case want_vtbl_amagicelem:
-       result = &PL_vtbl_amagicelem;
-       break;
-    case want_vtbl_backref:
-       result = &PL_vtbl_backref;
-       break;
-    case want_vtbl_utf8:
-       result = &PL_vtbl_utf8;
-       break;
-    default:
-       result = NULL;
-       break;
-    }
-    return (MGVTBL*)result;
+    return (vtbl_id < 0 || vtbl_id >= magic_vtable_max)
+       ? NULL : PL_magic_vtables + vtbl_id;
 }
 
 I32