"Bake" the values of PERL_REVISION, PERL_VERSION and PERL_SUBVERSION
Nicholas Clark [Wed, 7 Nov 2007 23:58:06 +0000 (23:58 +0000)]
into global variables (and hence a shared perl library). Additionally
under MULTIPLICITY record the size of the interpreter structure (total,
and for this version) and under PERL_GLOBAL_STRUCT the size of the
global variables structure. Coupled with PL_bincompat_options this will
allow 5.10.1 (and later), when compiled with a shared perl library, to
perform sanity checks in main() to verify that the shared library is
indeed binary compatible.

p4raw-id: //depot/perl@32238

embedvar.h
intrpvar.h
perl.h
perlapi.h
perlvars.h

index 26d5821..27623d0 100644 (file)
 #define PL_Gdollarzero_mutex   (my_vars->Gdollarzero_mutex)
 #define PL_fold_locale         (my_vars->Gfold_locale)
 #define PL_Gfold_locale                (my_vars->Gfold_locale)
+#define PL_global_struct_size  (my_vars->Gglobal_struct_size)
+#define PL_Gglobal_struct_size (my_vars->Gglobal_struct_size)
 #define PL_hexdigit            (my_vars->Ghexdigit)
 #define PL_Ghexdigit           (my_vars->Ghexdigit)
 #define PL_hints_mutex         (my_vars->Ghints_mutex)
 #define PL_Ghints_mutex                (my_vars->Ghints_mutex)
+#define PL_interpreter_size    (my_vars->Ginterpreter_size)
+#define PL_Ginterpreter_size   (my_vars->Ginterpreter_size)
+#define PL_interpreter_size_5_10_0     (my_vars->Ginterpreter_size_5_10_0)
+#define PL_Ginterpreter_size_5_10_0    (my_vars->Ginterpreter_size_5_10_0)
 #define PL_malloc_mutex                (my_vars->Gmalloc_mutex)
 #define PL_Gmalloc_mutex       (my_vars->Gmalloc_mutex)
 #define PL_mmap_page_size      (my_vars->Gmmap_page_size)
 #define PL_Gperlio_mutex       (my_vars->Gperlio_mutex)
 #define PL_ppaddr              (my_vars->Gppaddr)
 #define PL_Gppaddr             (my_vars->Gppaddr)
+#define PL_revision            (my_vars->Grevision)
+#define PL_Grevision           (my_vars->Grevision)
 #define PL_runops_dbg          (my_vars->Grunops_dbg)
 #define PL_Grunops_dbg         (my_vars->Grunops_dbg)
 #define PL_runops_std          (my_vars->Grunops_std)
 #define PL_Gsig_trapped                (my_vars->Gsig_trapped)
 #define PL_sigfpe_saved                (my_vars->Gsigfpe_saved)
 #define PL_Gsigfpe_saved       (my_vars->Gsigfpe_saved)
+#define PL_subversion          (my_vars->Gsubversion)
+#define PL_Gsubversion         (my_vars->Gsubversion)
 #define PL_sv_placeholder      (my_vars->Gsv_placeholder)
 #define PL_Gsv_placeholder     (my_vars->Gsv_placeholder)
 #define PL_thr_key             (my_vars->Gthr_key)
 #define PL_Gtimesbase          (my_vars->Gtimesbase)
 #define PL_use_safe_putenv     (my_vars->Guse_safe_putenv)
 #define PL_Guse_safe_putenv    (my_vars->Guse_safe_putenv)
+#define PL_version             (my_vars->Gversion)
+#define PL_Gversion            (my_vars->Gversion)
 #define PL_veto_cleanup                (my_vars->Gveto_cleanup)
 #define PL_Gveto_cleanup       (my_vars->Gveto_cleanup)
 #define PL_watch_pvx           (my_vars->Gwatch_pvx)
 #define PL_Gdo_undump          PL_do_undump
 #define PL_Gdollarzero_mutex   PL_dollarzero_mutex
 #define PL_Gfold_locale                PL_fold_locale
+#define PL_Gglobal_struct_size PL_global_struct_size
 #define PL_Ghexdigit           PL_hexdigit
 #define PL_Ghints_mutex                PL_hints_mutex
+#define PL_Ginterpreter_size   PL_interpreter_size
+#define PL_Ginterpreter_size_5_10_0    PL_interpreter_size_5_10_0
 #define PL_Gmalloc_mutex       PL_malloc_mutex
 #define PL_Gmmap_page_size     PL_mmap_page_size
 #define PL_Gmy_ctx_mutex       PL_my_ctx_mutex
 #define PL_Gperlio_fd_refcnt_size      PL_perlio_fd_refcnt_size
 #define PL_Gperlio_mutex       PL_perlio_mutex
 #define PL_Gppaddr             PL_ppaddr
+#define PL_Grevision           PL_revision
 #define PL_Grunops_dbg         PL_runops_dbg
 #define PL_Grunops_std         PL_runops_std
 #define PL_Gsh_path            PL_sh_path
 #define PL_Gsig_sv             PL_sig_sv
 #define PL_Gsig_trapped                PL_sig_trapped
 #define PL_Gsigfpe_saved       PL_sigfpe_saved
+#define PL_Gsubversion         PL_subversion
 #define PL_Gsv_placeholder     PL_sv_placeholder
 #define PL_Gthr_key            PL_thr_key
 #define PL_Gtimesbase          PL_timesbase
 #define PL_Guse_safe_putenv    PL_use_safe_putenv
+#define PL_Gversion            PL_version
 #define PL_Gveto_cleanup       PL_veto_cleanup
 #define PL_Gwatch_pvx          PL_watch_pvx
 
index 8a3dba2..5d583f0 100644 (file)
@@ -623,6 +623,12 @@ PERLVARI(Irehash_seed, UV, 0)              /* 582 hash initializer */
 
 PERLVARI(Iisarev, HV*, NULL) /* Reverse map of @ISA dependencies */
 
+/* The last unconditional member of the interpreter structure when 5.10.0 was
+   released. The offset of the end of this is baked into a global variable in 
+   any shared perl library which will allow a sanity test in future perl
+   releases.  */
+#define PERL_LAST_5_10_0_INTERP_MEMBER Iisarev
+
 #ifdef PERL_IMPLICIT_CONTEXT
 PERLVARI(Imy_cxt_size, int, 0)         /* size of PL_my_cxt_list */
 PERLVARI(Imy_cxt_list, void **, NULL) /* per-module array of MY_CXT pointers */
diff --git a/perl.h b/perl.h
index d81bc10..e26e475 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -4619,6 +4619,10 @@ typedef struct exitlistentry {
 #  define  FAKE_DEFAULT_SIGNAL_HANDLERS
 #endif
 
+#define PERL_PATCHLEVEL_H_IMPLICIT
+#include "patchlevel.h"
+#undef PERL_PATCHLEVEL_H_IMPLICIT
+
 #ifdef PERL_GLOBAL_STRUCT
 struct perl_vars {
 #  include "perlvars.h"
@@ -5839,11 +5843,6 @@ extern void moncontrol(int);
 #define NO_ENV_ARRAY_IN_MAIN
 #endif
 
-/* and finally... */
-#define PERL_PATCHLEVEL_H_IMPLICIT
-#include "patchlevel.h"
-#undef PERL_PATCHLEVEL_H_IMPLICIT
-
 /* These are used by Perl_pv_escape() and Perl_pv_pretty() 
  * are here so that they are available throughout the core 
  * NOTE that even though some are for _escape and some for _pretty
@@ -5924,4 +5923,3 @@ extern void moncontrol(int);
 */
 
 #endif /* Include guard */
-
index d924aff..42cac35 100644 (file)
--- a/perlapi.h
+++ b/perlapi.h
@@ -748,10 +748,16 @@ END_EXTERN_C
 #define PL_dollarzero_mutex    (*Perl_Gdollarzero_mutex_ptr(NULL))
 #undef  PL_fold_locale
 #define PL_fold_locale         (*Perl_Gfold_locale_ptr(NULL))
+#undef  PL_global_struct_size
+#define PL_global_struct_size  (*Perl_Gglobal_struct_size_ptr(NULL))
 #undef  PL_hexdigit
 #define PL_hexdigit            (*Perl_Ghexdigit_ptr(NULL))
 #undef  PL_hints_mutex
 #define PL_hints_mutex         (*Perl_Ghints_mutex_ptr(NULL))
+#undef  PL_interpreter_size
+#define PL_interpreter_size    (*Perl_Ginterpreter_size_ptr(NULL))
+#undef  PL_interpreter_size_5_10_0
+#define PL_interpreter_size_5_10_0     (*Perl_Ginterpreter_size_5_10_0_ptr(NULL))
 #undef  PL_malloc_mutex
 #define PL_malloc_mutex                (*Perl_Gmalloc_mutex_ptr(NULL))
 #undef  PL_mmap_page_size
@@ -778,6 +784,8 @@ END_EXTERN_C
 #define PL_perlio_mutex                (*Perl_Gperlio_mutex_ptr(NULL))
 #undef  PL_ppaddr
 #define PL_ppaddr              (*Perl_Gppaddr_ptr(NULL))
+#undef  PL_revision
+#define PL_revision            (*Perl_Grevision_ptr(NULL))
 #undef  PL_runops_dbg
 #define PL_runops_dbg          (*Perl_Grunops_dbg_ptr(NULL))
 #undef  PL_runops_std
@@ -796,6 +804,8 @@ END_EXTERN_C
 #define PL_sig_trapped         (*Perl_Gsig_trapped_ptr(NULL))
 #undef  PL_sigfpe_saved
 #define PL_sigfpe_saved                (*Perl_Gsigfpe_saved_ptr(NULL))
+#undef  PL_subversion
+#define PL_subversion          (*Perl_Gsubversion_ptr(NULL))
 #undef  PL_sv_placeholder
 #define PL_sv_placeholder      (*Perl_Gsv_placeholder_ptr(NULL))
 #undef  PL_thr_key
@@ -804,6 +814,8 @@ END_EXTERN_C
 #define PL_timesbase           (*Perl_Gtimesbase_ptr(NULL))
 #undef  PL_use_safe_putenv
 #define PL_use_safe_putenv     (*Perl_Guse_safe_putenv_ptr(NULL))
+#undef  PL_version
+#define PL_version             (*Perl_Gversion_ptr(NULL))
 #undef  PL_veto_cleanup
 #define PL_veto_cleanup                (*Perl_Gveto_cleanup_ptr(NULL))
 #undef  PL_watch_pvx
index 94a3f95..de3c63b 100644 (file)
@@ -160,3 +160,29 @@ PERLVARI(Gveto_cleanup,    int, FALSE)     /* exit without cleanup */
 PERLVARI(Grunops_std,  runops_proc_t,  MEMBER_TO_FPTR(Perl_runops_standard))
 PERLVARI(Grunops_dbg,  runops_proc_t,  MEMBER_TO_FPTR(Perl_runops_debug))
 
+
+/* These are baked at compile time into any shared perl library.
+   In future 5.10.x releases this will allow us in main() to sanity test the
+   library we're linking against.  */
+
+PERLVARI(Grevision,    U8,     PERL_REVISION)
+PERLVARI(Gversion,     U8,     PERL_VERSION)
+PERLVARI(Gsubversion,  U8,     PERL_SUBVERSION)
+
+#if defined(MULTIPLICITY)
+#  define PERL_INTERPRETER_SIZE_UPTO_MEMBER(member)                    \
+    STRUCT_OFFSET(struct interpreter, member) +                                \
+    sizeof(((struct interpreter*)0)->member)
+
+/* These might be useful.  */
+PERLVARI(Ginterpreter_size,    U16,    sizeof(struct interpreter))
+#if defined(PERL_GLOBAL_STRUCT)
+PERLVARI(Gglobal_struct_size,  U16,    sizeof(struct perl_vars))
+#endif
+
+/* This will be useful for subsequent releases, because this has to be the
+   same in your libperl as in main(), else you have a mismatch and must abort.
+*/
+PERLVARI(Ginterpreter_size_5_10_0, U16,
+        PERL_INTERPRETER_SIZE_UPTO_MEMBER(PERL_LAST_5_10_0_INTERP_MEMBER))
+#endif