This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
If the scalar has just been upgraded to SVt_RV, there's no way SvPVX
[perl5.git] / perl.h
diff --git a/perl.h b/perl.h
index 5da4f62..4da34ce 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -1,7 +1,7 @@
 /*    perl.h
  *
  *    Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- *    2000, 2001, 2002, 2003, 2004, 2005 by Larry Wall and others
+ *    2000, 2001, 2002, 2003, 2004, 2005, 2006, by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
 #  endif
 #endif
 
-#if defined(MULTIPLICITY)
-#  ifndef PERL_IMPLICIT_CONTEXT
-#    define PERL_IMPLICIT_CONTEXT
-#  endif
-#endif
-
 #ifdef PERL_GLOBAL_STRUCT_PRIVATE
 #  ifndef PERL_GLOBAL_STRUCT
 #    define PERL_GLOBAL_STRUCT
 #  endif
 #endif
+
 #ifdef PERL_GLOBAL_STRUCT
 #  ifndef MULTIPLICITY
 #    define MULTIPLICITY
 #  endif
 #endif
 
+#ifdef MULTIPLICITY
+#  ifndef PERL_IMPLICIT_CONTEXT
+#    define PERL_IMPLICIT_CONTEXT
+#  endif
+#endif
+
 /* undef WIN32 when building on Cygwin (for libwin32) - gph */
 #ifdef __CYGWIN__
 #   undef WIN32
 #  endif
 #endif
 
-#define pVAR    register struct perl_vars* my_vars PERL_UNUSED_DECL
+#define pVAR    register struct perl_vars* const my_vars PERL_UNUSED_DECL
 
 #ifdef PERL_GLOBAL_STRUCT
 #  define dVAR         pVAR    = (struct perl_vars*)PERL_GET_VARS()
 #    define MULTIPLICITY
 #  endif
 #  define tTHX PerlInterpreter*
-#  define sTHX (sizeof(tTHX) + (MEM_ALIGNBYTES - sizeof(tTHX)%MEM_ALIGNBYTES) % MEM_ALIGNBYTES)
 #  define pTHX register tTHX my_perl PERL_UNUSED_DECL
 #  define aTHX my_perl
 #  ifdef PERL_GLOBAL_STRUCT
 #endif
 
 #ifndef PERL_UNUSED_DECL
-#  ifdef HASATTRIBUTE_UNUSED
+#  if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus)
 #    define PERL_UNUSED_DECL __attribute__unused__
 #  else
 #    define PERL_UNUSED_DECL
 #  define PERL_UNUSED_VAR(x) ((void)x)
 #endif
 
+#ifdef USE_ITHREADS
+#  define PERL_UNUSED_CONTEXT PERL_UNUSED_ARG(my_perl)
+#else
+#  define PERL_UNUSED_CONTEXT
+#endif
+
 #define NOOP (void)0
 #define dNOOP extern int Perl___notused PERL_UNUSED_DECL
 
@@ -362,16 +368,6 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
 #define WITH_THX(s) STMT_START { dTHX; s; } STMT_END
 #define WITH_THR(s) WITH_THX(s)
 
-/*
- * SOFT_CAST can be used for args to prototyped functions to retain some
- * type checking; it only casts if the compiler does not know prototypes.
- */
-#if defined(CAN_PROTOTYPE) && defined(DEBUGGING_COMPILE)
-#define SOFT_CAST(type)        
-#else
-#define SOFT_CAST(type)        (type)
-#endif
-
 #ifndef BYTEORDER  /* Should never happen -- byteorder is in config.h */
 #   define BYTEORDER 0x1234
 #endif
@@ -422,7 +418,7 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
 #define TAINT_NOT      (PL_tainted = FALSE)
 #define TAINT_IF(c)    if (c) { PL_tainted = TRUE; }
 #define TAINT_ENV()    if (PL_tainting) { taint_env(); }
-#define TAINT_PROPER(s)        if (PL_tainting) { taint_proper(Nullch, s); }
+#define TAINT_PROPER(s)        if (PL_tainting) { taint_proper(NULL, s); }
 
 /* XXX All process group stuff is handled in pp_sys.c.  Should these
    defines move there?  If so, I could simplify this a lot. --AD  9/96.
@@ -822,7 +818,9 @@ int usleep(unsigned int);
 /* We no longer default to creating a new SV for GvSV.
    Do this before embed.  */
 #ifndef PERL_CREATE_GVSV
-#define PERL_DONT_CREATE_GVSV
+#  ifndef PERL_DONT_CREATE_GVSV
+#    define PERL_DONT_CREATE_GVSV
+#  endif
 #endif
 
 #if !defined(HAS_WAITPID) && !defined(HAS_WAIT4) || defined(HAS_WAITPID_RUNTIME)
@@ -838,6 +836,10 @@ int usleep(unsigned int);
  */
 #if !defined(PERL_FOR_X2P) && !(defined(WIN32)||defined(VMS))
 #  include "embed.h"
+#  ifndef PERL_MAD
+#    undef op_getmad
+#    define op_getmad(arg,pegop,slot) /*EMPTY*/
+#  endif
 #endif
 
 #define MEM_SIZE Size_t
@@ -2143,6 +2145,11 @@ struct RExC_state_t;
 
 typedef MEM_SIZE STRLEN;
 
+#ifdef PERL_MAD
+typedef struct token TOKEN;
+typedef struct madprop MADPROP;
+typedef struct nexttoken NEXTTOKE;
+#endif
 typedef struct op OP;
 typedef struct cop COP;
 typedef struct unop UNOP;
@@ -2318,6 +2325,10 @@ typedef struct clone_params CLONE_PARAMS;
 #if defined(VMS)
 #   include "vmsish.h"
 #   include "embed.h"
+#  ifndef PERL_MAD
+#    undef op_getmad
+#    define op_getmad(arg,pegop,slot) /*EMPTY*/
+#  endif
 #   define ISHISH "vms"
 #endif
 
@@ -2348,6 +2359,10 @@ typedef struct clone_params CLONE_PARAMS;
 #ifdef __SYMBIAN32__
 #   include "symbian/symbianish.h"
 #   include "embed.h"
+#  ifndef PERL_MAD
+#    undef op_getmad
+#    define op_getmad(arg,pegop,slot) /*EMPTY*/
+#  endif
 #   define ISHISH "symbian"
 #endif
 
@@ -2500,7 +2515,7 @@ typedef struct clone_params CLONE_PARAMS;
  * have HASATTRIBUTE_FORMAT).
  */
 
-#if defined __GNUC__
+#if defined __GNUC__ && !defined(__INTEL_COMPILER)
 #  if __GNUC__ >= 3 /* 3.0 -> */ /* XXX Verify this version */
 #    define HASATTRIBUTE_FORMAT
 #  endif
@@ -2956,9 +2971,20 @@ typedef pthread_key_t    perl_key;
    appropriate to call return.  In either case, include the lint directive.
  */
 #ifdef HASATTRIBUTE_NORETURN
-#  define NORETURN_FUNCTION_END /* NOT REACHED */
+#  define NORETURN_FUNCTION_END /* NOTREACHED */
 #else
-#  define NORETURN_FUNCTION_END /* NOT REACHED */ return 0
+#  define NORETURN_FUNCTION_END /* NOTREACHED */ return 0
+#endif
+
+#ifdef HAS_BUILTIN_EXPECT
+#  define EXPECT(expr,val)                  __builtin_expect(expr,val)
+#else
+#  define EXPECT(expr,val)                  (expr)
+#endif
+#define LIKELY(cond)                        EXPECT(cond,1)
+#define UNLIKELY(cond)                      EXPECT(cond,0)
+#ifdef HAS_BUILTIN_CHOOSE_EXPR
+/* placeholder */
 #endif
 
 /* Some unistd.h's give a prototype for pause() even though
@@ -2977,8 +3003,8 @@ typedef pthread_key_t     perl_key;
 #      define IOCPARM_LEN(x)  (((x) >> 16) & IOCPARM_MASK)
 #   else
 #      if defined(_IOC_SIZE) && defined(__GLIBC__)
-       /* on Linux systems we're safe */
-#          define IOCPARM_LEN(x) _IOC_SIZE(x)
+       /* on Linux systems we're safe; except when we're not [perl #38223] */
+#          define IOCPARM_LEN(x) (_IOC_SIZE(x) < 256 ? 256 : _IOC_SIZE(x))
 #      else
        /* otherwise guess at what's safe */
 #          define IOCPARM_LEN(x)       256
@@ -3053,6 +3079,23 @@ typedef        struct crypt_data {     /* straight from /usr/include/crypt.h */
 #  define USE_HASH_SEED
 #endif
 
+/* Win32 defines a type 'WORD' in windef.h. This conflicts with the enumerator
+ * 'WORD' defined in perly.h. The yytokentype enum is only a debugging aid, so
+ * it's not really needed.
+ */
+#if defined(WIN32)
+#  define YYTOKENTYPE
+#endif
+#include "perly.h"
+
+#ifdef PERL_MAD
+struct nexttoken {
+    YYSTYPE next_val;  /* value of next token, if any */
+    I32 next_type;     /* type of next token */
+    MADPROP *next_mad; /* everything else about that token */
+};
+#endif
+
 #include "regexp.h"
 #include "sv.h"
 #include "util.h"
@@ -3490,7 +3533,6 @@ Gid_t getegid (void);
 #define PERL_MAGIC_substr        'x' /* substr() lvalue */
 #define PERL_MAGIC_defelem       'y' /* Shadow "foreach" iterator variable /
                                        smart parameter vivification */
-#define PERL_MAGIC_glob                  '*' /* GV (typeglob) */
 #define PERL_MAGIC_arylen        '#' /* Array length ($#ary) */
 #define PERL_MAGIC_pos           '.' /* pos() lvalue */
 #define PERL_MAGIC_backref       '<' /* for weak ref data */
@@ -3503,9 +3545,8 @@ Gid_t getegid (void);
 #ifndef assert  /* <assert.h> might have been included somehow */
 #define assert(what)   PERL_DEB(                                       \
        ((what) ? ((void) 0) :                                          \
-           (Perl_croak(aTHX_ "Assertion %s failed: file \"" __FILE__   \
+           (Perl_croak_nocontext("Assertion %s failed: file \"" __FILE__ \
                        "\", line %d", STRINGIFY(what), __LINE__),      \
-           PerlProc_exit(1),                                           \
            (void) 0)))
 #endif
 
@@ -3657,7 +3698,7 @@ char *getlogin (void);
 /* Also rename() is affected by this */
 #ifdef UNLINK_ALL_VERSIONS /* Currently only makes sense for VMS */
 #define UNLINK unlnk
-I32 unlnk (const char*);
+I32 unlnk (pTHX_ const char*);
 #else
 #define UNLINK PerlLIO_unlink
 #endif
@@ -3727,6 +3768,34 @@ typedef Sighandler_t Sigsave_t;
 #  define MALLOC_TERM
 #endif
 
+#if defined(PERL_IMPLICIT_CONTEXT)
+
+struct perl_memory_debug_header;
+struct perl_memory_debug_header {
+  tTHX interpreter;
+#  ifdef PERL_POISON
+  MEM_SIZE size;
+#  endif
+  struct perl_memory_debug_header *prev;
+  struct perl_memory_debug_header *next;
+};
+
+#  define sTHX (sizeof(struct perl_memory_debug_header) + \
+       (MEM_ALIGNBYTES - sizeof(struct perl_memory_debug_header) \
+        %MEM_ALIGNBYTES) % MEM_ALIGNBYTES)
+
+#endif
+
+#ifdef PERL_TRACK_MEMPOOL
+#  define INIT_TRACK_MEMPOOL(header, interp)                   \
+       STMT_START {                                            \
+               (header).interpreter = (interp);                \
+               (header).prev = (header).next = &(header);      \
+       } STMT_END
+#  else
+#  define INIT_TRACK_MEMPOOL(header, interp)
+#endif
+
 
 typedef int (CPERLscope(*runops_proc_t)) (pTHX);
 typedef void (CPERLscope(*share_proc_t)) (pTHX_ SV *sv);
@@ -4019,6 +4088,9 @@ EXTCONST char* const PL_block_type[] = {
        "LOOP",
        "SUBST",
        "BLOCK",
+       "FORMAT",
+       "GIVEN",
+       "WHEN"
 };
 #else
 EXTCONST char* PL_block_type[];
@@ -4042,15 +4114,6 @@ END_EXTERN_C
 #endif
 #endif
 
-/* Win32 defines a type 'WORD' in windef.h. This conflicts with the enumerator
- * 'WORD' defined in perly.h. The yytokentype enum is only a debugging aid, so
- * it's not really needed.
- */
-#if defined(WIN32)
-#  define YYTOKENTYPE
-#endif
-#include "perly.h"
-
 #define LEX_NOTPARSING         11      /* borrowed from toke.c */
 
 typedef enum {
@@ -4283,6 +4346,12 @@ struct tempsym; /* defined in pp_pack.c */
 #if !defined(PERL_FOR_X2P)
 #  include "embedvar.h"
 #endif
+#ifndef PERL_MAD
+#  undef PL_madskills
+#  undef PL_xmlfp
+#  define PL_madskills 0
+#  define PL_xmlfp 0
+#endif
 
 /* Now include all the 'global' variables
  * If we don't have threads or multiple interpreters
@@ -4305,6 +4374,10 @@ END_EXTERN_C
 #if defined(WIN32)
 /* Now all the config stuff is setup we can include embed.h */
 #  include "embed.h"
+#  ifndef PERL_MAD
+#    undef op_getmad
+#    define op_getmad(arg,pegop,slot) /*EMPTY*/
+#  endif
 #endif
 
 #ifndef PERL_GLOBAL_STRUCT
@@ -4323,11 +4396,13 @@ END_EXTERN_C
 START_EXTERN_C
 
 #ifdef DOINIT
-#  define MGVTBL_SET(var,a,b,c,d,e,f,g) EXTCONST MGVTBL var = {a,b,c,d,e,f,g}
-#  define MGVTBL_SET_CONST_MAGIC_GET(var,a,b,c,d,e,f,g) EXTCONST MGVTBL var = {(int (*)(pTHX_ SV *, MAGIC *))a,b,c,d,e,f,g} /* Like MGVTBL_SET but with the get magic having a const MG* */
+#  define MGVTBL_SET(var,a,b,c,d,e,f,g,h) EXT MGVTBL var = {a,b,c,d,e,f,g,h}
+/* Like MGVTBL_SET but with the get magic having a const MG* */
+#  define MGVTBL_SET_CONST_MAGIC_GET(var,a,b,c,d,e,f,g,h) EXT MGVTBL var \
+    = {(int (*)(pTHX_ SV *, MAGIC *))a,b,c,d,e,f,g,h}
 #else
-#  define MGVTBL_SET(var,a,b,c,d,e,f,g) EXTCONST MGVTBL var
-#  define MGVTBL_SET_CONST_MAGIC_GET(var,a,b,c,d,e,f,g) EXTCONST MGVTBL var
+#  define MGVTBL_SET(var,a,b,c,d,e,f,g,h) EXT MGVTBL var
+#  define MGVTBL_SET_CONST_MAGIC_GET(var,a,b,c,d,e,f,g,h) EXT MGVTBL var
 #endif
 
 MGVTBL_SET(
@@ -4338,6 +4413,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4349,6 +4425,7 @@ MGVTBL_SET(
     MEMBER_TO_FPTR(Perl_magic_clear_all_env),
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4360,6 +4437,7 @@ MGVTBL_SET(
     MEMBER_TO_FPTR(Perl_magic_clearenv),
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4371,13 +4449,21 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
 #ifdef PERL_MICRO
 MGVTBL_SET(
     PL_vtbl_sigelem,
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL
 );
 
 #else
@@ -4389,6 +4475,7 @@ MGVTBL_SET(
     MEMBER_TO_FPTR(Perl_magic_clearsig),
     NULL,
     NULL,
+    NULL,
     NULL
 );
 #endif
@@ -4401,6 +4488,7 @@ MGVTBL_SET(
     MEMBER_TO_FPTR(Perl_magic_wipepack),
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4412,6 +4500,7 @@ MGVTBL_SET(
     MEMBER_TO_FPTR(Perl_magic_clearpack),
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4423,6 +4512,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4434,6 +4524,7 @@ MGVTBL_SET(
     MEMBER_TO_FPTR(Perl_magic_setisa),
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4445,6 +4536,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4456,6 +4548,7 @@ MGVTBL_SET_CONST_MAGIC_GET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4467,16 +4560,6 @@ MGVTBL_SET(
     NULL,
     MEMBER_TO_FPTR(Perl_magic_freearylen_p),
     NULL,
-    NULL
-);
-
-MGVTBL_SET(
-    PL_vtbl_glob,
-    MEMBER_TO_FPTR(Perl_magic_getglob),
-    MEMBER_TO_FPTR(Perl_magic_setglob),
-    NULL,
-    NULL,
-    NULL,
     NULL,
     NULL
 );
@@ -4489,6 +4572,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4500,6 +4584,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4511,6 +4596,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4522,6 +4608,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4533,6 +4620,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4544,6 +4632,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4555,6 +4644,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4566,6 +4656,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4577,6 +4668,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4588,6 +4680,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4599,6 +4692,7 @@ MGVTBL_SET(
     NULL,
     MEMBER_TO_FPTR(Perl_magic_freeregexp),
     NULL,
+    NULL,
     NULL
 );
 
@@ -4610,6 +4704,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4621,6 +4716,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 
@@ -4632,6 +4728,7 @@ MGVTBL_SET(
     NULL,
     MEMBER_TO_FPTR(Perl_magic_setamagic),
     NULL,
+    NULL,
     NULL
 );
 
@@ -4643,6 +4740,7 @@ MGVTBL_SET(
     NULL,
     MEMBER_TO_FPTR(Perl_magic_setamagic),
     NULL,
+    NULL,
     NULL
 );
 
@@ -4654,6 +4752,7 @@ MGVTBL_SET(
     NULL,
     MEMBER_TO_FPTR(Perl_magic_killbackrefs),
     NULL,
+    NULL,
     NULL
 );
 
@@ -4665,6 +4764,7 @@ MGVTBL_SET(
     NULL,
     MEMBER_TO_FPTR(Perl_magic_freeovrld),
     NULL,
+    NULL,
     NULL
 );
 
@@ -4676,6 +4776,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 #ifdef USE_LOCALE_COLLATE
@@ -4687,6 +4788,7 @@ MGVTBL_SET(
     NULL,
     NULL,
     NULL,
+    NULL,
     NULL
 );
 #endif
@@ -4725,7 +4827,10 @@ enum {
   to_sv_amg,   to_av_amg,
   to_hv_amg,   to_gv_amg,
   to_cv_amg,   iter_amg,
-  int_amg,     DESTROY_amg,
+  int_amg,     smart_amg,
+
+  /* Note: Perl_Gv_AMupdate() assumes that DESTROY is the last entry */
+  DESTROY_amg,
   max_amg_code
   /* Do not leave a trailing comma here.  C9X allows it, C89 doesn't. */
 };
@@ -4772,7 +4877,8 @@ EXTCONST char * const PL_AMG_names[NofAMmeth] = {
   "(${}",      "(@{}",
   "(%{}",      "(*{}",
   "(&{}",      "(<>",
-  "(int",      "DESTROY",
+  "(int",      "(~~",
+  "DESTROY"
 };
 #else
 EXTCONST char * PL_AMG_names[NofAMmeth];
@@ -5070,6 +5176,7 @@ typedef struct am_table_short AMTS;
  * Code that uses these macros is responsible for the following:
  * 1. #define MY_CXT_KEY to a unique string, e.g.
  *    "DynaLoader::_guts" XS_VERSION
+ *    XXX in the current implementation, this string is ignored.
  * 2. Declare a typedef named my_cxt_t that is a structure that contains
  *    all the data that needs to be interpreter-local.
  * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t.
@@ -5086,35 +5193,30 @@ typedef struct am_table_short AMTS;
 /* This must appear in all extensions that define a my_cxt_t structure,
  * right after the definition (i.e. at file scope).  The non-threads
  * case below uses it to declare the data as static. */
-#define START_MY_CXT
-
-/* Fetches the SV that keeps the per-interpreter data. */
-#define dMY_CXT_SV \
-       SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY,             \
-                                 sizeof(MY_CXT_KEY)-1, TRUE)
+#define START_MY_CXT static int my_cxt_index = -1;
 
 /* This declaration should be used within all functions that use the
  * interpreter-local data. */
 #define dMY_CXT        \
-       dMY_CXT_SV;                                                     \
-       my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*, SvUV(my_cxt_sv))
+       my_cxt_t *my_cxtp = (my_cxt_t *)PL_my_cxt_list[my_cxt_index]
+#define dMY_CXT_INTERP(my_perl)        \
+       my_cxt_t *my_cxtp = (my_cxt_t *)(my_perl)->Imy_cxt_list[my_cxt_index]
 
 /* Creates and zeroes the per-interpreter data.
  * (We allocate my_cxtp in a Perl SV so that it will be released when
  * the interpreter goes away.) */
 #define MY_CXT_INIT \
-       dMY_CXT_SV;                                                     \
-       /* newSV() allocates one more than needed */                    \
-       my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
-       Zero(my_cxtp, 1, my_cxt_t);                                     \
-       sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
+       my_cxt_t *my_cxtp = \
+           (my_cxt_t*)Perl_my_cxt_init(aTHX_ &my_cxt_index, sizeof(my_cxt_t))
+#define MY_CXT_INIT_INTERP(my_perl) \
+       my_cxt_t *my_cxtp = \
+           (my_cxt_t*)Perl_my_cxt_init(my_perl, &my_cxt_index, sizeof(my_cxt_t))
 
 /* Clones the per-interpreter data. */
 #define MY_CXT_CLONE \
-       dMY_CXT_SV;                                                     \
        my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
-       Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t);\
-       sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
+       Copy(PL_my_cxt_list[my_cxt_index], my_cxtp, 1, my_cxt_t);\
+       PL_my_cxt_list[my_cxt_index] = my_cxtp                          \
 
 /* This macro must be used to access members of the my_cxt_t structure.
  * e.g. MYCXT.some_data */
@@ -5129,7 +5231,7 @@ typedef struct am_table_short AMTS;
 #define aMY_CXT_       aMY_CXT,
 #define _aMY_CXT       ,aMY_CXT
 
-#else /* USE_ITHREADS */
+#else /* PERL_IMPLICIT_CONTEXT */
 
 #define START_MY_CXT   static my_cxt_t my_cxt;
 #define dMY_CXT_SV     dNOOP
@@ -5145,7 +5247,7 @@ typedef struct am_table_short AMTS;
 #define aMY_CXT_
 #define _aMY_CXT
 
-#endif /* !defined(USE_ITHREADS) */
+#endif /* !defined(PERL_IMPLICIT_CONTEXT) */
 
 #ifdef I_FCNTL
 #  include <fcntl.h>