Add a comment to force emacs to use C mode.
[p5sagit/Devel-Size.git] / Size.xs
diff --git a/Size.xs b/Size.xs
index 7ac3d3e..9dd4f0d 100644 (file)
--- a/Size.xs
+++ b/Size.xs
@@ -1,3 +1,5 @@
+/* -*- mode: C -*- */
+
 #define PERL_NO_GET_CONTEXT
 
 #include "EXTERN.h"
 #ifndef SvRV_const
 #  define SvRV_const(rv) SvRV(rv)
 #endif
+#ifndef SvOOK_offset
+#  define SvOOK_offset(sv, len) STMT_START { len = SvIVX(sv); } STMT_END
+#endif
+
+#if PERL_VERSION < 6
+#  define PL_opargs opargs
+#  define PL_op_name op_name
+#endif
 
 #ifdef _MSC_VER 
 /* "structured exception" handling is a Microsoft extension to C and C++.
@@ -138,7 +148,7 @@ free_tracking_at(void **tv, int level)
        /* Nodes */
        do {
            if (tv[i]) {
-               free_tracking_at(tv[i], level);
+               free_tracking_at((void **) tv[i], level);
                Safefree(tv[i]);
            }
        } while (i--);
@@ -173,7 +183,7 @@ free_state(struct state *st)
 #define SOME_RECURSION 1
 #define TOTAL_SIZE_RECURSION 2
 
-static bool sv_size(pTHX_ struct state *, const SV *const, const int recurse);
+static void sv_size(pTHX_ struct state *, const SV *const, const int recurse);
 
 typedef enum {
     OPc_NULL,   /* 0 */
@@ -188,6 +198,13 @@ typedef enum {
     OPc_PVOP,   /* 9 */
     OPc_LOOP,   /* 10 */
     OPc_COP /* 11 */
+#ifdef OA_CONDOP
+    , OPc_CONDOP /* 12 */
+#endif
+#ifdef OA_GVOP
+    , OPc_GVOP /* 13 */
+#endif
+
 } opclass;
 
 static opclass
@@ -233,9 +250,17 @@ cc_opclass(const OP * const o)
         case OA_SVOP: TAG;
         return OPc_SVOP;
 
+#ifdef OA_PADOP
         case OA_PADOP: TAG;
         return OPc_PADOP;
+#endif
 
+#ifdef OA_GVOP
+        case OA_GVOP: TAG;
+        return OPc_GVOP;
+#endif
+
+#ifdef OA_PVOP_OR_SVOP
         case OA_PVOP_OR_SVOP: TAG;
             /*
              * Character translations (tr///) are usually a PVOP, keeping a 
@@ -246,6 +271,7 @@ cc_opclass(const OP * const o)
              */
         return (o->op_private & (OPpTRANS_TO_UTF|OPpTRANS_FROM_UTF))
             ? OPc_SVOP : OPc_PVOP;
+#endif
 
         case OA_LOOP: TAG;
         return OPc_LOOP;
@@ -295,6 +321,11 @@ cc_opclass(const OP * const o)
             return OPc_BASEOP;
         else
             return OPc_PVOP;
+
+#ifdef OA_CONDOP
+        case OA_CONDOP: TAG;
+           return OPc_CONDOP;
+#endif
         }
         warn("Devel::Size: Can't determine class of operator %s, assuming BASEOP\n",
          PL_op_name[o->op_type]);
@@ -303,11 +334,6 @@ cc_opclass(const OP * const o)
     return OPc_BASEOP;
 }
 
-
-#if !defined(NV)
-#define NV double
-#endif
-
 /* Figure out how much magic is attached to the SV and return the
    size */
 static void
@@ -317,12 +343,12 @@ magic_size(pTHX_ const SV * const thing, struct state *st) {
   /* Have we seen the magic pointer?  (NULL has always been seen before)  */
   while (check_new(st, magic_pointer)) {
     st->total_size += sizeof(MAGIC);
+    /* magic vtables aren't freed when magic is freed, so don't count them.
+       (They are static structures. Anything that assumes otherwise is buggy.)
+    */
+
 
     TRY_TO_CATCH_SEGV {
-        /* Have we seen the magic vtable? */
-        if (check_new(st, magic_pointer->mg_virtual)) {
-          st->total_size += sizeof(MGVTBL);
-        }
        sv_size(aTHX_ st, magic_pointer->mg_obj, TOTAL_SIZE_RECURSION);
        if (magic_pointer->mg_len == HEf_SVKEY) {
            sv_size(aTHX_ st, (SV *)magic_pointer->mg_ptr, TOTAL_SIZE_RECURSION);
@@ -392,38 +418,45 @@ op_size(pTHX_ const OP * const baseop, struct state *st)
            TAG;break;
        case OPc_UNOP: TAG;
            st->total_size += sizeof(struct unop);
-           op_size(aTHX_ cUNOPx(baseop)->op_first, st);
+           op_size(aTHX_ ((UNOP *)baseop)->op_first, st);
            TAG;break;
        case OPc_BINOP: TAG;
            st->total_size += sizeof(struct binop);
-           op_size(aTHX_ cBINOPx(baseop)->op_first, st);
-           op_size(aTHX_ cBINOPx(baseop)->op_last, st);
+           op_size(aTHX_ ((BINOP *)baseop)->op_first, st);
+           op_size(aTHX_ ((BINOP *)baseop)->op_last, st);
            TAG;break;
        case OPc_LOGOP: TAG;
            st->total_size += sizeof(struct logop);
-           op_size(aTHX_ cBINOPx(baseop)->op_first, st);
-           op_size(aTHX_ cLOGOPx(baseop)->op_other, st);
+           op_size(aTHX_ ((BINOP *)baseop)->op_first, st);
+           op_size(aTHX_ ((LOGOP *)baseop)->op_other, st);
+           TAG;break;
+#ifdef OA_CONDOP
+       case OPc_CONDOP: TAG;
+           st->total_size += sizeof(struct condop);
+           op_size(aTHX_ ((BINOP *)baseop)->op_first, st);
+           op_size(aTHX_ ((CONDOP *)baseop)->op_true, st);
+           op_size(aTHX_ ((CONDOP *)baseop)->op_false, st);
            TAG;break;
+#endif
        case OPc_LISTOP: TAG;
            st->total_size += sizeof(struct listop);
-           op_size(aTHX_ cLISTOPx(baseop)->op_first, st);
-           op_size(aTHX_ cLISTOPx(baseop)->op_last, st);
+           op_size(aTHX_ ((LISTOP *)baseop)->op_first, st);
+           op_size(aTHX_ ((LISTOP *)baseop)->op_last, st);
            TAG;break;
        case OPc_PMOP: TAG;
            st->total_size += sizeof(struct pmop);
-           op_size(aTHX_ cPMOPx(baseop)->op_first, st);
-           op_size(aTHX_ cPMOPx(baseop)->op_last, st);
+           op_size(aTHX_ ((PMOP *)baseop)->op_first, st);
+           op_size(aTHX_ ((PMOP *)baseop)->op_last, st);
 #if PERL_VERSION < 9 || (PERL_VERSION == 9 && PERL_SUBVERSION < 5)
-           op_size(aTHX_ cPMOPx(baseop)->op_pmreplroot, st);
-           op_size(aTHX_ cPMOPx(baseop)->op_pmreplstart, st);
-           op_size(aTHX_ (OP *)cPMOPx(baseop)->op_pmnext, st);
+           op_size(aTHX_ ((PMOP *)baseop)->op_pmreplroot, st);
+           op_size(aTHX_ ((PMOP *)baseop)->op_pmreplstart, st);
 #endif
            /* This is defined away in perl 5.8.x, but it is in there for
               5.6.x */
 #ifdef PM_GETRE
-           regex_size(PM_GETRE(cPMOPx(baseop)), st);
+           regex_size(PM_GETRE((PMOP *)baseop), st);
 #else
-           regex_size(cPMOPx(baseop)->op_pmregexp, st);
+           regex_size(((PMOP *)baseop)->op_pmregexp, st);
 #endif
            TAG;break;
        case OPc_SVOP: TAG;
@@ -431,22 +464,30 @@ op_size(pTHX_ const OP * const baseop, struct state *st)
            if (!(baseop->op_type == OP_AELEMFAST
                  && baseop->op_flags & OPf_SPECIAL)) {
                /* not an OP_PADAV replacement */
-               sv_size(aTHX_ st, cSVOPx(baseop)->op_sv, SOME_RECURSION);
+               sv_size(aTHX_ st, ((SVOP *)baseop)->op_sv, SOME_RECURSION);
            }
            TAG;break;
+#ifdef OA_PADOP
       case OPc_PADOP: TAG;
          st->total_size += sizeof(struct padop);
          TAG;break;
+#endif
+#ifdef OA_GVOP
+      case OPc_GVOP: TAG;
+         st->total_size += sizeof(struct gvop);
+         sv_size(aTHX_ st, ((GVOP *)baseop)->op_gv, SOME_RECURSION);
+         TAG;break;
+#endif
        case OPc_PVOP: TAG;
-           check_new_and_strlen(st, cPVOPx(baseop)->op_pv);
+           check_new_and_strlen(st, ((PVOP *)baseop)->op_pv);
            TAG;break;
        case OPc_LOOP: TAG;
            st->total_size += sizeof(struct loop);
-           op_size(aTHX_ cLOOPx(baseop)->op_first, st);
-           op_size(aTHX_ cLOOPx(baseop)->op_last, st);
-           op_size(aTHX_ cLOOPx(baseop)->op_redoop, st);
-           op_size(aTHX_ cLOOPx(baseop)->op_nextop, st);
-           op_size(aTHX_ cLOOPx(baseop)->op_lastop, st);
+           op_size(aTHX_ ((LOOP *)baseop)->op_first, st);
+           op_size(aTHX_ ((LOOP *)baseop)->op_last, st);
+           op_size(aTHX_ ((LOOP *)baseop)->op_redoop, st);
+           op_size(aTHX_ ((LOOP *)baseop)->op_nextop, st);
+           op_size(aTHX_ ((LOOP *)baseop)->op_lastop, st);
            TAG;break;
        case OPc_COP: TAG;
         {
@@ -488,108 +529,116 @@ op_size(pTHX_ const OP * const baseop, struct state *st)
 #  define SVt_LAST 16
 #endif
 
+#ifdef PURIFY
+#  define MAYBE_PURIFY(normal, pure) (pure)
+#  define MAYBE_OFFSET(struct_name, member) 0
+#else
+#  define MAYBE_PURIFY(normal, pure) (normal)
+#  define MAYBE_OFFSET(struct_name, member) STRUCT_OFFSET(struct_name, member)
+#endif
+
 const U8 body_sizes[SVt_LAST] = {
 #if PERL_VERSION < 9
-     0,                                               /* SVt_NULL */
-     sizeof(IV),                                      /* SVt_IV */
-     sizeof(NV),                                      /* SVt_NV */
-     sizeof(XRV),                                     /* SVt_RV */
-     sizeof(XPV),                                     /* SVt_PV */
-     sizeof(XPVIV),                                   /* SVt_PVIV */
-     sizeof(XPVNV),                                   /* SVt_PVNV */
-     sizeof(XPVMG),                                   /* SVt_PVMG */
-     sizeof(XPVBM),                                   /* SVt_PVBM */
-     sizeof(XPVLV),                                   /* SVt_PVLV */
-     sizeof(XPVAV),                                   /* SVt_PVAV */
-     sizeof(XPVHV),                                   /* SVt_PVHV */
-     sizeof(XPVCV),                                   /* SVt_PVCV */
-     sizeof(XPVGV),                                   /* SVt_PVGV */
-     sizeof(XPVFM),                                   /* SVt_PVFM */
-     sizeof(XPVIO)                                    /* SVt_PVIO */
+     0,                                                       /* SVt_NULL */
+     MAYBE_PURIFY(sizeof(IV), sizeof(XPVIV)),                 /* SVt_IV */
+     MAYBE_PURIFY(sizeof(NV), sizeof(XPVNV)),                 /* SVt_NV */
+     sizeof(XRV),                                             /* SVt_RV */
+     sizeof(XPV),                                             /* SVt_PV */
+     sizeof(XPVIV),                                           /* SVt_PVIV */
+     sizeof(XPVNV),                                           /* SVt_PVNV */
+     sizeof(XPVMG),                                           /* SVt_PVMG */
+     sizeof(XPVBM),                                           /* SVt_PVBM */
+     sizeof(XPVLV),                                           /* SVt_PVLV */
+     sizeof(XPVAV),                                           /* SVt_PVAV */
+     sizeof(XPVHV),                                           /* SVt_PVHV */
+     sizeof(XPVCV),                                           /* SVt_PVCV */
+     sizeof(XPVGV),                                           /* SVt_PVGV */
+     sizeof(XPVFM),                                           /* SVt_PVFM */
+     sizeof(XPVIO)                                            /* SVt_PVIO */
 #elif PERL_VERSION == 10 && PERL_SUBVERSION == 0
-     0,                                               /* SVt_NULL */
-     0,                                               /* SVt_BIND */
-     0,                                               /* SVt_IV */
-     sizeof(NV),                                      /* SVt_NV */
-     0,                                               /* SVt_RV */
-     sizeof(xpv_allocated),                           /* SVt_PV */
-     sizeof(xpviv_allocated),                         /* SVt_PVIV */
-     sizeof(XPVNV),                                   /* SVt_PVNV */
-     sizeof(XPVMG),                                   /* SVt_PVMG */
-     sizeof(XPVGV),                                   /* SVt_PVGV */
-     sizeof(XPVLV),                                   /* SVt_PVLV */
-     sizeof(xpvav_allocated),                         /* SVt_PVAV */
-     sizeof(xpvhv_allocated),                         /* SVt_PVHV */
-     sizeof(xpvcv_allocated),                         /* SVt_PVCV */
-     sizeof(xpvfm_allocated),                         /* SVt_PVFM */
-     sizeof(XPVIO),                                   /* SVt_PVIO */
+     0,                                                       /* SVt_NULL */
+     0,                                                       /* SVt_BIND */
+     0,                                                       /* SVt_IV */
+     MAYBE_PURIFY(sizeof(NV), sizeof(XPVNV)),                 /* SVt_NV */
+     0,                                                       /* SVt_RV */
+     MAYBE_PURIFY(sizeof(xpv_allocated), sizeof(XPV)),        /* SVt_PV */
+     MAYBE_PURIFY(sizeof(xpviv_allocated), sizeof(XPVIV)),/* SVt_PVIV */
+     sizeof(XPVNV),                                           /* SVt_PVNV */
+     sizeof(XPVMG),                                           /* SVt_PVMG */
+     sizeof(XPVGV),                                           /* SVt_PVGV */
+     sizeof(XPVLV),                                           /* SVt_PVLV */
+     MAYBE_PURIFY(sizeof(xpvav_allocated), sizeof(XPVAV)),/* SVt_PVAV */
+     MAYBE_PURIFY(sizeof(xpvhv_allocated), sizeof(XPVHV)),/* SVt_PVHV */
+     MAYBE_PURIFY(sizeof(xpvcv_allocated), sizeof(XPVCV)),/* SVt_PVCV */
+     MAYBE_PURIFY(sizeof(xpvfm_allocated), sizeof(XPVFM)),/* SVt_PVFM */
+     sizeof(XPVIO),                                           /* SVt_PVIO */
 #elif PERL_VERSION == 10 && PERL_SUBVERSION == 1
-     0,                                               /* SVt_NULL */
-     0,                                               /* SVt_BIND */
-     0,                                               /* SVt_IV */
-     sizeof(NV),                                      /* SVt_NV */
-     0,                                               /* SVt_RV */
-     sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur),       /* SVt_PV */
-     sizeof(XPVIV) - STRUCT_OFFSET(XPV, xpv_cur),     /* SVt_PVIV */
-     sizeof(XPVNV),                                   /* SVt_PVNV */
-     sizeof(XPVMG),                                   /* SVt_PVMG */
-     sizeof(XPVGV),                                   /* SVt_PVGV */
-     sizeof(XPVLV),                                   /* SVt_PVLV */
-     sizeof(XPVAV) - STRUCT_OFFSET(XPVAV, xav_fill),  /* SVt_PVAV */
-     sizeof(XPVHV) - STRUCT_OFFSET(XPVHV, xhv_fill),  /* SVt_PVHV */
-     sizeof(XPVCV) - STRUCT_OFFSET(XPVCV, xpv_cur),   /* SVt_PVCV */
-     sizeof(XPVFM) - STRUCT_OFFSET(XPVFM, xpv_cur),   /* SVt_PVFM */
-     sizeof(XPVIO)                                    /* SVt_PVIO */
+     0,                                                       /* SVt_NULL */
+     0,                                                       /* SVt_BIND */
+     0,                                                       /* SVt_IV */
+     MAYBE_PURIFY(sizeof(NV), sizeof(XPVNV)),                 /* SVt_NV */
+     0,                                                       /* SVt_RV */
+     sizeof(XPV) - MAYBE_OFFSET(XPV, xpv_cur),                /* SVt_PV */
+     sizeof(XPVIV) - MAYBE_OFFSET(XPV, xpv_cur),              /* SVt_PVIV */
+     sizeof(XPVNV),                                           /* SVt_PVNV */
+     sizeof(XPVMG),                                           /* SVt_PVMG */
+     sizeof(XPVGV),                                           /* SVt_PVGV */
+     sizeof(XPVLV),                                           /* SVt_PVLV */
+     sizeof(XPVAV) - MAYBE_OFFSET(XPVAV, xav_fill),           /* SVt_PVAV */
+     sizeof(XPVHV) - MAYBE_OFFSET(XPVHV, xhv_fill),           /* SVt_PVHV */
+     sizeof(XPVCV) - MAYBE_OFFSET(XPVCV, xpv_cur),            /* SVt_PVCV */
+     sizeof(XPVFM) - MAYBE_OFFSET(XPVFM, xpv_cur),            /* SVt_PVFM */
+     sizeof(XPVIO)                                            /* SVt_PVIO */
 #elif PERL_VERSION < 13
-     0,                                               /* SVt_NULL */
-     0,                                               /* SVt_BIND */
-     0,                                               /* SVt_IV */
-     sizeof(NV),                                      /* SVt_NV */
-     sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur),       /* SVt_PV */
-     sizeof(XPVIV) - STRUCT_OFFSET(XPV, xpv_cur),     /* SVt_PVIV */
-     sizeof(XPVNV),                                   /* SVt_PVNV */
-     sizeof(XPVMG),                                   /* SVt_PVMG */
-     sizeof(regexp) - STRUCT_OFFSET(regexp, xpv_cur), /* SVt_REGEXP */
-     sizeof(XPVGV),                                   /* SVt_PVGV */
-     sizeof(XPVLV),                                   /* SVt_PVLV */
-     sizeof(XPVAV) - STRUCT_OFFSET(XPVAV, xav_fill),  /* SVt_PVAV */
-     sizeof(XPVHV) - STRUCT_OFFSET(XPVHV, xhv_fill),  /* SVt_PVHV */
-     sizeof(XPVCV) - STRUCT_OFFSET(XPVCV, xpv_cur),   /* SVt_PVCV */
-     sizeof(XPVFM) - STRUCT_OFFSET(XPVFM, xpv_cur),   /* SVt_PVFM */
-     sizeof(XPVIO)                                    /* SVt_PVIO */
+     0,                                                       /* SVt_NULL */
+     0,                                                       /* SVt_BIND */
+     0,                                                       /* SVt_IV */
+     MAYBE_PURIFY(sizeof(NV), sizeof(XPVNV)),                 /* SVt_NV */
+     sizeof(XPV) - MAYBE_OFFSET(XPV, xpv_cur),                /* SVt_PV */
+     sizeof(XPVIV) - MAYBE_OFFSET(XPV, xpv_cur),              /* SVt_PVIV */
+     sizeof(XPVNV),                                           /* SVt_PVNV */
+     sizeof(XPVMG),                                           /* SVt_PVMG */
+     sizeof(regexp) - MAYBE_OFFSET(regexp, xpv_cur),          /* SVt_REGEXP */
+     sizeof(XPVGV),                                           /* SVt_PVGV */
+     sizeof(XPVLV),                                           /* SVt_PVLV */
+     sizeof(XPVAV) - MAYBE_OFFSET(XPVAV, xav_fill),           /* SVt_PVAV */
+     sizeof(XPVHV) - MAYBE_OFFSET(XPVHV, xhv_fill),           /* SVt_PVHV */
+     sizeof(XPVCV) - MAYBE_OFFSET(XPVCV, xpv_cur),            /* SVt_PVCV */
+     sizeof(XPVFM) - MAYBE_OFFSET(XPVFM, xpv_cur),            /* SVt_PVFM */
+     sizeof(XPVIO)                                            /* SVt_PVIO */
 #else
-     0,                                               /* SVt_NULL */
-     0,                                               /* SVt_BIND */
-     0,                                               /* SVt_IV */
-     sizeof(NV),                                      /* SVt_NV */
-     sizeof(XPV) - STRUCT_OFFSET(XPV, xpv_cur),       /* SVt_PV */
-     sizeof(XPVIV) - STRUCT_OFFSET(XPV, xpv_cur),     /* SVt_PVIV */
-     sizeof(XPVNV) - STRUCT_OFFSET(XPV, xpv_cur),     /* SVt_PVNV */
-     sizeof(XPVMG),                                   /* SVt_PVMG */
-     sizeof(regexp),                                  /* SVt_REGEXP */
-     sizeof(XPVGV),                                   /* SVt_PVGV */
-     sizeof(XPVLV),                                   /* SVt_PVLV */
-     sizeof(XPVAV),                                   /* SVt_PVAV */
-     sizeof(XPVHV),                                   /* SVt_PVHV */
-     sizeof(XPVCV),                                   /* SVt_PVCV */
-     sizeof(XPVFM),                                   /* SVt_PVFM */
-     sizeof(XPVIO)                                    /* SVt_PVIO */
+     0,                                                       /* SVt_NULL */
+     0,                                                       /* SVt_BIND */
+     0,                                                       /* SVt_IV */
+     MAYBE_PURIFY(sizeof(NV), sizeof(XPVNV)),                 /* SVt_NV */
+     sizeof(XPV) - MAYBE_OFFSET(XPV, xpv_cur),                /* SVt_PV */
+     sizeof(XPVIV) - MAYBE_OFFSET(XPV, xpv_cur),              /* SVt_PVIV */
+     sizeof(XPVNV) - MAYBE_OFFSET(XPV, xpv_cur),              /* SVt_PVNV */
+     sizeof(XPVMG),                                           /* SVt_PVMG */
+     sizeof(regexp),                                          /* SVt_REGEXP */
+     sizeof(XPVGV),                                           /* SVt_PVGV */
+     sizeof(XPVLV),                                           /* SVt_PVLV */
+     sizeof(XPVAV),                                           /* SVt_PVAV */
+     sizeof(XPVHV),                                           /* SVt_PVHV */
+     sizeof(XPVCV),                                           /* SVt_PVCV */
+     sizeof(XPVFM),                                           /* SVt_PVFM */
+     sizeof(XPVIO)                                            /* SVt_PVIO */
 #endif
 };
 
-static bool
+static void
 sv_size(pTHX_ struct state *const st, const SV * const orig_thing,
        const int recurse) {
   const SV *thing = orig_thing;
   U32 type;
 
   if(!check_new(st, thing))
-      return FALSE;
+      return;
 
   type = SvTYPE(thing);
   if (type > SVt_LAST) {
       warn("Devel::Size: Unknown variable type: %d encountered\n", type);
-      return TRUE;
+      return;
   }
   st->total_size += sizeof(SV) + body_sizes[type];
 
@@ -757,35 +806,21 @@ sv_size(pTHX_ struct state *const st, const SV * const orig_thing,
        st->total_size += SvLEN(thing);
 
     if(SvOOK(thing)) {
-        st->total_size += SvIVX(thing);
+       STRLEN len;
+       SvOOK_offset(thing, len);
+       st->total_size += len;
     }
     TAG;break;
 
   }
-  return TRUE;
+  return;
 }
 
-/* Frustratingly, the vtables aren't const in perl.h
-   gcc is happy enough to have non-const initialisers in a static array.
-   VC seems not to be. (Is it actually treating the file as C++?)
-   So do the maximally portable thing, unless we know it's gcc, in which case
-   we can do the more space efficient version.  */
-
-#if __GNUC__
-void *vtables[] = {
-#include "vtables.inc"
-    NULL
-};
-#endif
-
 static struct state *
 new_state(pTHX)
 {
     SV *warn_flag;
     struct state *st;
-#if __GNUC__
-    void **vt_p = vtables;
-#endif
 
     Newxz(st, 1, struct state);
     st->go_yell = TRUE;
@@ -798,11 +833,8 @@ new_state(pTHX)
     check_new(st, &PL_sv_undef);
     check_new(st, &PL_sv_no);
     check_new(st, &PL_sv_yes);
-#if __GNUC__
-    while(*vt_p)
-       check_new(st, *vt_p++);
-#else
-#include "vtables.inc"
+#if PERL_VERSION > 8 || (PERL_VERSION == 8 && PERL_SUBVERSION > 0)
+    check_new(st, &PL_sv_placeholder);
 #endif
     return st;
 }