+#ifdef USE_ITHREADS
+#define BSET_cop_file(cop, arg) CopFILE_set(cop,arg)
+#define BSET_cop_stashpv(cop, arg) CopSTASHPV_set(cop,arg)
+#else
+/* this works now that Sarathy's changed the CopFILE_set macro to do the SvREFCNT_inc()
+ -- BKS 6-2-2000 */
+/* that really meant the actual CopFILEGV_set */
+#define BSET_cop_filegv(cop, arg) CopFILEGV_set(cop,arg)
+#define BSET_cop_stash(cop,arg) CopSTASH_set(cop,(HV*)arg)
+#endif
+
+/* this is simply stolen from the code in newATTRSUB() */
+#define BSET_push_begin(ary,cv) \
+ STMT_START { \
+ I32 oldscope = PL_scopestack_ix; \
+ ENTER; \
+ SAVECOPFILE(&PL_compiling); \
+ SAVECOPLINE(&PL_compiling); \
+ if (!PL_beginav) \
+ PL_beginav = newAV(); \
+ av_push(PL_beginav, (SV*)cv); \
+ GvCV(CvGV(cv)) = 0; /* cv has been hijacked */\
+ call_list(oldscope, PL_beginav); \
+ PL_curcop = &PL_compiling; \
+ PL_compiling.op_private = (U8)(PL_hints & HINT_PRIVATE_MASK);\
+ LEAVE; \
+ } STMT_END
+#define BSET_push_init(ary,cv) \
+ STMT_START { \
+ av_unshift((PL_initav ? PL_initav : \
+ (PL_initav = newAV(), PL_initav)), 1); \
+ av_store(PL_initav, 0, cv); \
+ } STMT_END
+#define BSET_push_end(ary,cv) \
+ STMT_START { \
+ av_unshift((PL_endav ? PL_endav : \
+ (PL_endav = newAV(), PL_endav)), 1); \
+ av_store(PL_endav, 0, cv); \
+ } STMT_END
+#define BSET_OBJ_STORE(obj, ix) \
+ ((I32)ix > bstate->bs_obj_list_fill ? \
+ bset_obj_store(aTHX_ bstate, obj, (I32)ix) : \
+ (bstate->bs_obj_list[ix] = obj), \
+ bstate->bs_ix = ix+1)
+#define BSET_OBJ_STOREX(obj) \
+ (bstate->bs_ix > bstate->bs_obj_list_fill ? \
+ bset_obj_store(aTHX_ bstate, obj, bstate->bs_ix) : \
+ (bstate->bs_obj_list[bstate->bs_ix] = obj), \
+ bstate->bs_ix++)
+
+#define BSET_signal(cv, name) \
+ mg_set(*hv_store(GvHV(gv_fetchpv("SIG", TRUE, SVt_PVHV)), \
+ name, strlen(name), cv, 0))
+
+#define BSET_xhv_name(hv, name) hv_name_set((HV*)hv, name, strlen(name), 0)
+#define BSET_cop_arybase(c, b) CopARYBASE_set(c, b)
+#define BSET_cop_warnings(c, w) \
+ STMT_START { \
+ if (specialWARN((STRLEN *)w)) { \
+ c->cop_warnings = (STRLEN *)w; \
+ } else { \
+ STRLEN len; \
+ const char *const p = SvPV_const(w, len); \
+ c->cop_warnings = \
+ Perl_new_warnings_bitfield(aTHX_ NULL, p, len); \
+ SvREFCNT_dec(w); \
+ } \
+ } STMT_END
+#define BSET_gp_file(gv, file) \
+ STMT_START { \
+ STRLEN len = strlen(file); \
+ U32 hash; \
+ PERL_HASH(hash, file, len); \
+ if(GvFILE_HEK(gv)) { \
+ Perl_unshare_hek(aTHX_ GvFILE_HEK(gv)); \
+ } \
+ GvGP(gv)->gp_file_hek = share_hek(file, len, hash); \
+ Safefree(file); \
+ } STMT_END
+
+/* NOTE: the bytecode header only sanity-checks the bytecode. If a script cares about
+ * what version of Perl it's being called under, it should do a 'use 5.006_001' or
+ * equivalent. However, since the header includes checks requiring an exact match in
+ * ByteLoader versions (we can't guarantee forward compatibility), you don't
+ * need to specify one:
+ * use ByteLoader;
+ * is all you need.
+ * -- BKS, June 2000
+*/
+
+#define HEADER_FAIL(f) \
+ Perl_croak(aTHX_ "Invalid bytecode for this architecture: " f)
+#define HEADER_FAIL1(f, arg1) \
+ Perl_croak(aTHX_ "Invalid bytecode for this architecture: " f, arg1)
+#define HEADER_FAIL2(f, arg1, arg2) \
+ Perl_croak(aTHX_ "Invalid bytecode for this architecture: " f, arg1, arg2)
+
+#define BYTECODE_HEADER_CHECK \
+ STMT_START { \
+ U32 sz = 0; \
+ strconst str; \
+ \
+ BGET_U32(sz); /* Magic: 'PLBC' */ \
+ if (sz != 0x43424c50) { \
+ HEADER_FAIL1("bad magic (want 0x43424c50, got %#x)", (int)sz); \
+ } \
+ BGET_strconst(str); /* archname */ \
+ if (strNE(str, ARCHNAME)) { \
+ HEADER_FAIL2("wrong architecture (want %s, you have %s)",str,ARCHNAME); \
+ } \
+ BGET_strconst(str); /* ByteLoader version */ \
+ if (strNE(str, VERSION)) { \
+ HEADER_FAIL2("mismatched ByteLoader versions (want %s, you have %s)", \
+ str, VERSION); \
+ } \
+ BGET_U32(sz); /* ivsize */ \
+ if (sz != IVSIZE) { \
+ HEADER_FAIL("different IVSIZE"); \
+ } \
+ BGET_U32(sz); /* ptrsize */ \
+ if (sz != PTRSIZE) { \
+ HEADER_FAIL("different PTRSIZE"); \
+ } \
+ } STMT_END