This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
(and _5x I expect) VMS config procedure patch
[perl5.git] / bytecode.h
1 typedef char *pvcontents;
2 typedef char *strconst;
3 typedef U32 PV;
4 typedef char *op_tr_array;
5 typedef int comment_t;
6 typedef SV *svindex;
7 typedef OP *opindex;
8 typedef IV IV64;
9
10 #ifdef INDIRECT_BGET_MACROS
11 #define BGET_FREAD(argp, len, nelem)    \
12          bs.fread((char*)(argp),(len),(nelem),bs.data)
13 #define BGET_FGETC() bs.fgetc(bs.data)
14 #else
15 #define BGET_FREAD(argp, len, nelem) PerlIO_read(fp, (argp), (len)*(nelem))
16 #define BGET_FGETC() PerlIO_getc(fp)
17 #endif /* INDIRECT_BGET_MACROS */
18
19 #define BGET_U32(arg)   \
20         BGET_FREAD(&arg, sizeof(U32), 1); arg = PerlSock_ntohl((U32)arg)
21 #define BGET_I32(arg)   \
22         BGET_FREAD(&arg, sizeof(I32), 1); arg = (I32)PerlSock_ntohl((U32)arg)
23 #define BGET_U16(arg)   \
24         BGET_FREAD(&arg, sizeof(U16), 1); arg = PerlSock_ntohs((U16)arg)
25 #define BGET_U8(arg)    arg = BGET_FGETC()
26
27 #if INDIRECT_BGET_MACROS
28 #define BGET_PV(arg)    STMT_START {    \
29         BGET_U32(arg);                  \
30         if (arg)                        \
31             bs.freadpv(arg, bs.data);   \
32         else {                          \
33             PL_bytecode_pv.xpv_pv = 0;          \
34             PL_bytecode_pv.xpv_len = 0;         \
35             PL_bytecode_pv.xpv_cur = 0;         \
36         }                               \
37     } STMT_END
38 #else
39 #define BGET_PV(arg)    STMT_START {            \
40         BGET_U32(arg);                          \
41         if (arg) {                              \
42             New(666, PL_bytecode_pv.xpv_pv, arg, char); \
43             PerlIO_read(fp, PL_bytecode_pv.xpv_pv, arg);        \
44             PL_bytecode_pv.xpv_len = arg;                       \
45             PL_bytecode_pv.xpv_cur = arg - 1;           \
46         } else {                                \
47             PL_bytecode_pv.xpv_pv = 0;                  \
48             PL_bytecode_pv.xpv_len = 0;                 \
49             PL_bytecode_pv.xpv_cur = 0;                 \
50         }                                       \
51     } STMT_END
52 #endif /* INDIRECT_BGET_MACROS */
53
54 #define BGET_comment_t(arg) \
55         do { arg = BGET_FGETC(); } while (arg != '\n' && arg != EOF)
56
57 /*
58  * In the following, sizeof(IV)*4 is just a way of encoding 32 on 64-bit-IV
59  * machines such that 32-bit machine compilers don't whine about the shift
60  * count being too high even though the code is never reached there.
61  */
62 #define BGET_IV64(arg) STMT_START {                     \
63         U32 hi, lo;                                     \
64         BGET_U32(hi);                                   \
65         BGET_U32(lo);                                   \
66         if (sizeof(IV) == 8)                            \
67             arg = (IV) (hi << (sizeof(IV)*4) | lo);     \
68         else if (((I32)hi == -1 && (I32)lo < 0)         \
69                  || ((I32)hi == 0 && (I32)lo >= 0)) {   \
70             arg = (I32)lo;                              \
71         }                                               \
72         else {                                          \
73             PL_bytecode_iv_overflows++;                         \
74             arg = 0;                                    \
75         }                                               \
76     } STMT_END
77
78 #define BGET_op_tr_array(arg) do {      \
79         unsigned short *ary;            \
80         int i;                          \
81         New(666, ary, 256, unsigned short); \
82         BGET_FREAD(ary, 256, 2);        \
83         for (i = 0; i < 256; i++)       \
84             ary[i] = PerlSock_ntohs(ary[i]);    \
85         arg = (char *) ary;             \
86     } while (0)
87
88 #define BGET_pvcontents(arg)    arg = PL_bytecode_pv.xpv_pv
89 #define BGET_strconst(arg) STMT_START { \
90         for (arg = PL_tokenbuf; (*arg = BGET_FGETC()); arg++) /* nothing */; \
91         arg = PL_tokenbuf;                      \
92     } STMT_END
93
94 #define BGET_double(arg) STMT_START {   \
95         char *str;                      \
96         BGET_strconst(str);             \
97         arg = atof(str);                \
98     } STMT_END
99
100 #define BGET_objindex(arg, type) STMT_START {   \
101         U32 ix;                                 \
102         BGET_U32(ix);                           \
103         arg = (type)PL_bytecode_obj_list[ix];           \
104     } STMT_END
105 #define BGET_svindex(arg) BGET_objindex(arg, svindex)
106 #define BGET_opindex(arg) BGET_objindex(arg, opindex)
107
108 #define BSET_ldspecsv(sv, arg) sv = PL_specialsv_list[arg]
109                                     
110 #define BSET_sv_refcnt_add(svrefcnt, arg)       svrefcnt += arg
111 #define BSET_gp_refcnt_add(gprefcnt, arg)       gprefcnt += arg
112 #define BSET_gp_share(sv, arg) STMT_START {     \
113         gp_free((GV*)sv);                       \
114         GvGP(sv) = GvGP(arg);                   \
115     } STMT_END
116
117 #define BSET_gv_fetchpv(sv, arg)        sv = (SV*)gv_fetchpv(arg, TRUE, SVt_PV)
118 #define BSET_gv_stashpv(sv, arg)        sv = (SV*)gv_stashpv(arg, TRUE)
119 #define BSET_sv_magic(sv, arg)          sv_magic(sv, Nullsv, arg, 0, 0)
120 #define BSET_mg_pv(mg, arg)     mg->mg_ptr = arg; mg->mg_len = PL_bytecode_pv.xpv_cur
121 #define BSET_sv_upgrade(sv, arg)        (void)SvUPGRADE(sv, arg)
122 #define BSET_xpv(sv)    do {    \
123         SvPV_set(sv, PL_bytecode_pv.xpv_pv);    \
124         SvCUR_set(sv, PL_bytecode_pv.xpv_cur);  \
125         SvLEN_set(sv, PL_bytecode_pv.xpv_len);  \
126     } while (0)
127 #define BSET_av_extend(sv, arg) av_extend((AV*)sv, arg)
128
129 #define BSET_av_push(sv, arg)   av_push((AV*)sv, arg)
130 #define BSET_hv_store(sv, arg)  \
131         hv_store((HV*)sv, PL_bytecode_pv.xpv_pv, PL_bytecode_pv.xpv_cur, arg, 0)
132 #define BSET_pv_free(pv)        Safefree(pv.xpv_pv)
133 #define BSET_pregcomp(o, arg) \
134         ((PMOP*)o)->op_pmregexp = arg ? \
135                 CALLREGCOMP(arg, arg + PL_bytecode_pv.xpv_cur, ((PMOP*)o)) : 0
136 #define BSET_newsv(sv, arg)     sv = NEWSV(666,0); SvUPGRADE(sv, arg)
137 #define BSET_newop(o, arg)      o = (OP*)safemalloc(optype_size[arg])
138 #define BSET_newopn(o, arg) STMT_START {        \
139         OP *oldop = o;                          \
140         BSET_newop(o, arg);                     \
141         oldop->op_next = o;                     \
142     } STMT_END
143
144 #define BSET_ret(foo) return
145
146 /*
147  * Kludge special-case workaround for OP_MAPSTART
148  * which needs the ppaddr for OP_GREPSTART. Blech.
149  */
150 #define BSET_op_type(o, arg) STMT_START {       \
151         o->op_type = arg;                       \
152         if (arg == OP_MAPSTART)                 \
153             arg = OP_GREPSTART;                 \
154         o->op_ppaddr = ppaddr[arg];             \
155     } STMT_END
156 #define BSET_op_ppaddr(o, arg) croak("op_ppaddr not yet implemented")
157 #define BSET_curpad(pad, arg) pad = AvARRAY(arg)
158
159 #define BSET_OBJ_STORE(obj, ix)         \
160         (I32)ix > PL_bytecode_obj_list_fill ?   \
161         bset_obj_store(obj, (I32)ix) : (PL_bytecode_obj_list[ix] = obj)