1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
|
/* op.h
*
* Copyright (c) 1991-1994, Larry Wall
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
*/
/*
* The fields of BASEOP are:
* op_next Pointer to next ppcode to execute after this one.
* (Top level pre-grafted op points to first op,
* but this is replaced when op is grafted in, when
* this op will point to the real next op, and the new
* parent takes over role of remembering starting op.)
* op_ppaddr Pointer to current ppcode's function.
* op_type The type of the operation.
* op_flags Flags common to all operations. See OPf_* below.
* op_private Flags peculiar to a particular operation (BUT,
* by default, set to the number of children until
* the operation is privatized by a check routine,
* which may or may not check number of children).
*/
typedef U32 PADOFFSET;
#define NOT_IN_PAD ((PADOFFSET) -1)
#ifdef DEBUGGING_OPS
#define OPCODE opcode
#else
#define OPCODE U16
#endif
#define BASEOP \
OP* op_next; \
OP* op_sibling; \
OP* (*op_ppaddr)(); \
PADOFFSET op_targ; \
OPCODE op_type; \
U16 op_seq; \
U8 op_flags; \
U8 op_private;
#define GIMME (op->op_flags & OPf_KNOW ? op->op_flags & OPf_LIST : dowantarray())
/* Public flags */
#define OPf_LIST 1 /* Do operator in list context. */
#define OPf_KNOW 2 /* Context is known. */
#define OPf_KIDS 4 /* There is a firstborn child. */
#define OPf_PARENS 8 /* This operator was parenthesized. */
/* (Or block needs explicit scope entry.) */
#define OPf_REF 16 /* Certified reference. */
/* (Return container, not containee). */
#define OPf_MOD 32 /* Will modify (lvalue). */
#define OPf_STACKED 64 /* Some arg is arriving on the stack. */
#define OPf_SPECIAL 128 /* Do something weird for this op: */
/* On local LVAL, don't init local value. */
/* On OP_SORT, subroutine is inlined. */
/* On OP_NOT, inversion was implicit. */
/* On OP_LEAVE, don't restore curpm. */
/* On truncate, we truncate filehandle */
/* On control verbs, we saw no label */
/* On flipflop, we saw ... instead of .. */
/* On UNOPs, saw bare parens, e.g. eof(). */
/* On OP_ENTERSUB || OP_NULL, saw a "do". */
/* Private for lvalues */
#define OPpLVAL_INTRO 128 /* Lvalue must be localized */
/* Private for OP_AASSIGN */
#define OPpASSIGN_COMMON 64 /* Left & right have syms in common. */
/* Private for OP_SASSIGN */
#define OPpASSIGN_BACKWARDS 64 /* Left & right switched. */
/* Private for OP_TRANS */
#define OPpTRANS_SQUASH 16
#define OPpTRANS_DELETE 32
#define OPpTRANS_COMPLEMENT 64
/* Private for OP_REPEAT */
#define OPpREPEAT_DOLIST 64 /* List replication. */
/* Private for OP_ENTERSUB, OP_RV2?V, OP_?ELEM */
/* (lower bits carry hints) */
#define OPpENTERSUB_AMPER 8 /* Used & form to call. */
#define OPpENTERSUB_DB 16 /* Debug subroutine. */
#define OPpDEREF_AV 32 /* Want ref to AV. */
#define OPpDEREF_HV 64 /* Want ref to HV. */
/* Private for OP_CONST */
#define OPpCONST_ENTERED 16 /* Has been entered as symbol. */
#define OPpCONST_ARYBASE 32 /* Was a $[ translated to constant. */
#define OPpCONST_BARE 64 /* Was a bare word (filehandle?). */
/* Private for OP_FLIP/FLOP */
#define OPpFLIP_LINENUM 64 /* Range arg potentially a line num. */
/* Private for OP_LIST */
#define OPpLIST_GUESSED 64 /* Guessed that pushmark was needed. */
/* Private for OP_LEAVE and friends */
#define OPpLEAVE_VOID 64 /* No need to copy out values. */
struct op {
BASEOP
};
struct unop {
BASEOP
OP * op_first;
};
struct binop {
BASEOP
OP * op_first;
OP * op_last;
};
struct logop {
BASEOP
OP * op_first;
OP * op_other;
};
struct condop {
BASEOP
OP * op_first;
OP * op_true;
OP * op_false;
};
struct listop {
BASEOP
OP * op_first;
OP * op_last;
U32 op_children;
};
struct pmop {
BASEOP
OP * op_first;
OP * op_last;
U32 op_children;
OP * op_pmreplroot;
OP * op_pmreplstart;
PMOP * op_pmnext; /* list of all scanpats */
REGEXP * op_pmregexp; /* compiled expression */
SV * op_pmshort; /* for a fast bypass of execute() */
U16 op_pmflags;
U16 op_pmpermflags;
char op_pmslen;
};
#define PMf_USED 0x0001 /* pm has been used once already */
#define PMf_ONCE 0x0002 /* use pattern only once per reset */
#define PMf_SCANFIRST 0x0004 /* initial constant not anchored */
#define PMf_ALL 0x0008 /* initial constant is whole pat */
#define PMf_SKIPWHITE 0x0010 /* skip leading whitespace for split */
#define PMf_FOLD 0x0020 /* case insensitivity */
#define PMf_CONST 0x0040 /* subst replacement is constant */
#define PMf_KEEP 0x0080 /* keep 1st runtime pattern forever */
#define PMf_GLOBAL 0x0100 /* pattern had a g modifier */
#define PMf_RUNTIME 0x0200 /* pattern coming in on the stack */
#define PMf_EVAL 0x0400 /* evaluating replacement as expr */
#define PMf_WHITE 0x0800 /* pattern is \s+ */
#define PMf_MULTILINE 0x1000 /* assume multiple lines */
#define PMf_SINGLELINE 0x2000 /* assume single line */
#define PMf_UNUSED 0x4000 /* (unused) */
#define PMf_EXTENDED 0x8000 /* chuck embedded whitespace */
struct svop {
BASEOP
SV * op_sv;
};
struct gvop {
BASEOP
GV * op_gv;
};
struct pvop {
BASEOP
char * op_pv;
};
struct loop {
BASEOP
OP * op_first;
OP * op_last;
U32 op_children;
OP * op_redoop;
OP * op_nextop;
OP * op_lastop;
};
#define cUNOP ((UNOP*)op)
#define cBINOP ((BINOP*)op)
#define cLISTOP ((LISTOP*)op)
#define cLOGOP ((LOGOP*)op)
#define cCONDOP ((CONDOP*)op)
#define cPMOP ((PMOP*)op)
#define cSVOP ((SVOP*)op)
#define cGVOP ((GVOP*)op)
#define cPVOP ((PVOP*)op)
#define cCOP ((COP*)op)
#define cLOOP ((LOOP*)op)
#define cUNOPo ((UNOP*)o)
#define cBINOPo ((BINOP*)o)
#define cLISTOPo ((LISTOP*)o)
#define cLOGOPo ((LOGOP*)o)
#define cCONDOPo ((CONDOP*)o)
#define cPMOPo ((PMOP*)o)
#define cSVOPo ((SVOP*)o)
#define cGVOPo ((GVOP*)o)
#define cPVOPo ((PVOP*)o)
#define cCVOPo ((CVOP*)o)
#define cCOPo ((COP*)o)
#define cLOOPo ((LOOP*)o)
#define kUNOP ((UNOP*)kid)
#define kBINOP ((BINOP*)kid)
#define kLISTOP ((LISTOP*)kid)
#define kLOGOP ((LOGOP*)kid)
#define kCONDOP ((CONDOP*)kid)
#define kPMOP ((PMOP*)kid)
#define kSVOP ((SVOP*)kid)
#define kGVOP ((GVOP*)kid)
#define kPVOP ((PVOP*)kid)
#define kCOP ((COP*)kid)
#define kLOOP ((LOOP*)kid)
#define Nullop Null(OP*)
/* Lowest byte of opargs */
#define OA_MARK 1
#define OA_FOLDCONST 2
#define OA_RETSCALAR 4
#define OA_TARGET 8
#define OA_RETINTEGER 16
#define OA_OTHERINT 32
#define OA_DANGEROUS 64
#define OA_DEFGV 128
#define OASHIFT 8
/* Remaining nybbles of opargs */
#define OA_SCALAR 1
#define OA_LIST 2
#define OA_AVREF 3
#define OA_HVREF 4
#define OA_CVREF 5
#define OA_FILEREF 6
#define OA_SCALARREF 7
#define OA_OPTIONAL 8
|