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