| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
/* |
|
2
|
|
|
|
|
|
|
*---------------------------------------------------------------------------- |
|
3
|
|
|
|
|
|
|
* Wanted - ~/Wanted.xs |
|
4
|
|
|
|
|
|
|
* Version v0.1.0 |
|
5
|
|
|
|
|
|
|
* Copyright(c) 2025 DEGUEST Pte. Ltd. |
|
6
|
|
|
|
|
|
|
* Original author: Robin Houston |
|
7
|
|
|
|
|
|
|
* Modified by: Jacques Deguest <jack@deguest.jp> |
|
8
|
|
|
|
|
|
|
* Created 2025/05/16 |
|
9
|
|
|
|
|
|
|
* Modified 2025/05/24 |
|
10
|
|
|
|
|
|
|
* All rights reserved |
|
11
|
|
|
|
|
|
|
* |
|
12
|
|
|
|
|
|
|
* This program is free software; you can redistribute it and/or modify it |
|
13
|
|
|
|
|
|
|
* under the same terms as Perl itself. |
|
14
|
|
|
|
|
|
|
* |
|
15
|
|
|
|
|
|
|
* Description: |
|
16
|
|
|
|
|
|
|
* XS implementation for the Wanted Perl module, providing low-level |
|
17
|
|
|
|
|
|
|
* functions to inspect and manipulate Perl's context stack and op tree. |
|
18
|
|
|
|
|
|
|
*---------------------------------------------------------------------------- |
|
19
|
|
|
|
|
|
|
*/ |
|
20
|
|
|
|
|
|
|
#include "EXTERN.h" |
|
21
|
|
|
|
|
|
|
#include "perl.h" |
|
22
|
|
|
|
|
|
|
#include "XSUB.h" |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
/* Between 5.9.1 and 5.9.2 the retstack was removed, and the return op is now stored on the cxstack. */ |
|
25
|
|
|
|
|
|
|
#define HAS_RETSTACK (\ |
|
26
|
|
|
|
|
|
|
PERL_REVISION < 5 || \ |
|
27
|
|
|
|
|
|
|
(PERL_REVISION == 5 && PERL_VERSION < 9) || \ |
|
28
|
|
|
|
|
|
|
(PERL_REVISION == 5 && PERL_VERSION == 9 && PERL_SUBVERSION < 2) \ |
|
29
|
|
|
|
|
|
|
) |
|
30
|
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
/* Define PERL_VERSION_GE, PERL_VERSION_LT, PERL_VERSION_LE if not already defined (Perl < 5.24.0) */ |
|
32
|
|
|
|
|
|
|
#ifndef PERL_VERSION_GE |
|
33
|
|
|
|
|
|
|
#define PERL_VERSION_GE(major, minor, patch) \ |
|
34
|
|
|
|
|
|
|
(PERL_REVISION > (major) || \ |
|
35
|
|
|
|
|
|
|
(PERL_REVISION == (major) && (PERL_VERSION > (minor) || \ |
|
36
|
|
|
|
|
|
|
(PERL_VERSION == (minor) && PERL_SUBVERSION >= (patch))))) |
|
37
|
|
|
|
|
|
|
#endif |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
#ifndef PERL_VERSION_LT |
|
40
|
|
|
|
|
|
|
#define PERL_VERSION_LT(major, minor, patch) \ |
|
41
|
|
|
|
|
|
|
(PERL_REVISION < (major) || \ |
|
42
|
|
|
|
|
|
|
(PERL_REVISION == (major) && (PERL_VERSION < (minor) || \ |
|
43
|
|
|
|
|
|
|
(PERL_VERSION == (minor) && PERL_SUBVERSION < (patch))))) |
|
44
|
|
|
|
|
|
|
#endif |
|
45
|
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
#ifndef PERL_VERSION_LE |
|
47
|
|
|
|
|
|
|
#define PERL_VERSION_LE(major, minor, patch) \ |
|
48
|
|
|
|
|
|
|
(PERL_REVISION < (major) || \ |
|
49
|
|
|
|
|
|
|
(PERL_REVISION == (major) && (PERL_VERSION < (minor) || \ |
|
50
|
|
|
|
|
|
|
(PERL_VERSION == (minor) && PERL_SUBVERSION <= (patch))))) |
|
51
|
|
|
|
|
|
|
#endif |
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
#define PERL_HAS_FREE_OS_BUG (PERL_VERSION_GE(5, 22, 0) && PERL_VERSION_LE(5, 24, 0)) |
|
54
|
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
#define ENABLE_DOUBLE_RETURN_HACKS 1 |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
/* After 5.10, the CxLVAL macro was added. */ |
|
58
|
|
|
|
|
|
|
#ifndef CxLVAL |
|
59
|
|
|
|
|
|
|
# define CxLVAL(cx) cx->blk_sub.lval |
|
60
|
|
|
|
|
|
|
#endif |
|
61
|
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
#ifndef OpSIBLING |
|
63
|
|
|
|
|
|
|
# define OpSIBLING(o) o->op_sibling |
|
64
|
|
|
|
|
|
|
#endif |
|
65
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
/* Stolen from B.xs */ |
|
67
|
|
|
|
|
|
|
#ifdef PERL_OBJECT |
|
68
|
|
|
|
|
|
|
#undef PL_op_name |
|
69
|
|
|
|
|
|
|
#undef PL_opargs |
|
70
|
|
|
|
|
|
|
#undef PL_op_desc |
|
71
|
|
|
|
|
|
|
#define PL_op_name (get_op_names()) |
|
72
|
|
|
|
|
|
|
#define PL_opargs (get_opargs()) |
|
73
|
|
|
|
|
|
|
#define PL_op_desc (get_op_descs()) |
|
74
|
|
|
|
|
|
|
#endif |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
/* Define oplist and numop types */ |
|
77
|
|
|
|
|
|
|
#define OPLIST_MAX 50 |
|
78
|
|
|
|
|
|
|
typedef struct { |
|
79
|
|
|
|
|
|
|
U16 numop_num; |
|
80
|
|
|
|
|
|
|
OP* numop_op; |
|
81
|
|
|
|
|
|
|
} numop; |
|
82
|
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
typedef struct { |
|
84
|
|
|
|
|
|
|
U16 length; |
|
85
|
|
|
|
|
|
|
numop ops[OPLIST_MAX]; |
|
86
|
|
|
|
|
|
|
} oplist; |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
#define new_oplist (oplist*) malloc(sizeof(oplist)) |
|
89
|
|
|
|
|
|
|
#define init_oplist(l) l->length = 0 |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
/* Function declarations */ |
|
92
|
|
|
|
|
|
|
numop* lastnumop(oplist* l); |
|
93
|
|
|
|
|
|
|
OP* lastop(oplist* l); |
|
94
|
|
|
|
|
|
|
oplist* pushop(oplist* l, OP* o, U16 i); |
|
95
|
|
|
|
|
|
|
oplist* find_ancestors_from(OP* start, OP* next, oplist* l); |
|
96
|
|
|
|
|
|
|
I32 count_list (OP* parent, OP* returnop); |
|
97
|
|
|
|
|
|
|
I32 count_slice (OP* o); |
|
98
|
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
/* Stolen from pp_ctl.c (with modifications) */ |
|
100
|
|
|
|
|
|
|
/* |
|
101
|
|
|
|
|
|
|
* dopoptosub_at - Scans the given context stack for the nearest subroutine or format block. |
|
102
|
|
|
|
|
|
|
* |
|
103
|
|
|
|
|
|
|
* Arguments: |
|
104
|
|
|
|
|
|
|
* PERL_CONTEXT *cxstk - The context stack to search. |
|
105
|
|
|
|
|
|
|
* I32 startingblock - The starting index from which to scan downward. |
|
106
|
|
|
|
|
|
|
* |
|
107
|
|
|
|
|
|
|
* Return: |
|
108
|
|
|
|
|
|
|
* I32 - The index of the found subroutine or format block, or -1 if none is found. |
|
109
|
|
|
|
|
|
|
* |
|
110
|
|
|
|
|
|
|
* Description: |
|
111
|
|
|
|
|
|
|
* This is a helper function to locate the closest CXt_SUB or CXt_FORMAT in a given stack. |
|
112
|
|
|
|
|
|
|
* It is used in walking the context stack and is central to call depth resolution. |
|
113
|
|
|
|
|
|
|
* |
|
114
|
|
|
|
|
|
|
* Internal: |
|
115
|
|
|
|
|
|
|
* Used by dopoptosub() to implement context stack traversal. |
|
116
|
|
|
|
|
|
|
*/ |
|
117
|
|
|
|
|
|
|
I32 |
|
118
|
9479
|
|
|
|
|
|
dopoptosub_at(pTHX_ PERL_CONTEXT *cxstk, I32 startingblock) |
|
119
|
|
|
|
|
|
|
{ |
|
120
|
|
|
|
|
|
|
dTHR; |
|
121
|
|
|
|
|
|
|
I32 i; |
|
122
|
|
|
|
|
|
|
PERL_CONTEXT *cx; |
|
123
|
9479
|
50
|
|
|
|
|
if (!cxstk) return -1; |
|
124
|
14489
|
100
|
|
|
|
|
for (i = startingblock; i >= 0; i--) |
|
125
|
|
|
|
|
|
|
{ |
|
126
|
12976
|
|
|
|
|
|
cx = &cxstk[i]; |
|
127
|
12976
|
100
|
|
|
|
|
switch (CxTYPE(cx)) |
|
128
|
|
|
|
|
|
|
{ |
|
129
|
5010
|
|
|
|
|
|
default: |
|
130
|
5010
|
|
|
|
|
|
continue; |
|
131
|
7966
|
|
|
|
|
|
case CXt_SUB: |
|
132
|
|
|
|
|
|
|
case CXt_FORMAT: |
|
133
|
|
|
|
|
|
|
DEBUG_l( Perl_deb(aTHX_ "(Found sub #%ld)\n", (long)i)); |
|
134
|
7966
|
|
|
|
|
|
return i; |
|
135
|
|
|
|
|
|
|
} |
|
136
|
|
|
|
|
|
|
} |
|
137
|
1513
|
|
|
|
|
|
return i; |
|
138
|
|
|
|
|
|
|
} |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
/* |
|
141
|
|
|
|
|
|
|
* dopoptosub - Convenience wrapper around dopoptosub_at using the current cxstack. |
|
142
|
|
|
|
|
|
|
* |
|
143
|
|
|
|
|
|
|
* Arguments: |
|
144
|
|
|
|
|
|
|
* I32 startingblock - Start index into cxstack to scan for a subroutine context. |
|
145
|
|
|
|
|
|
|
* |
|
146
|
|
|
|
|
|
|
* Return: |
|
147
|
|
|
|
|
|
|
* I32 - The index of the found subroutine or format block, or -1 if not found. |
|
148
|
|
|
|
|
|
|
* |
|
149
|
|
|
|
|
|
|
* Description: |
|
150
|
|
|
|
|
|
|
* This function uses the current 'cxstack' and is typically used to locate |
|
151
|
|
|
|
|
|
|
* the active subroutine context for the current execution stack. |
|
152
|
|
|
|
|
|
|
* |
|
153
|
|
|
|
|
|
|
* Internal: |
|
154
|
|
|
|
|
|
|
* Used by upcontext() and upcontext_plus() to traverse the context stack. |
|
155
|
|
|
|
|
|
|
*/ |
|
156
|
|
|
|
|
|
|
I32 |
|
157
|
1737
|
|
|
|
|
|
dopoptosub(pTHX_ I32 startingblock) |
|
158
|
|
|
|
|
|
|
{ |
|
159
|
|
|
|
|
|
|
dTHR; |
|
160
|
1737
|
50
|
|
|
|
|
if (!cxstack) return -1; |
|
161
|
1737
|
|
|
|
|
|
return dopoptosub_at(aTHX_ cxstack, startingblock); |
|
162
|
|
|
|
|
|
|
} |
|
163
|
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
/* |
|
165
|
|
|
|
|
|
|
* upcontext - Retrieves the subroutine context 'count' levels up the stack. |
|
166
|
|
|
|
|
|
|
* |
|
167
|
|
|
|
|
|
|
* Arguments: |
|
168
|
|
|
|
|
|
|
* I32 count - The number of subroutine contexts to go up. |
|
169
|
|
|
|
|
|
|
* |
|
170
|
|
|
|
|
|
|
* Return: |
|
171
|
|
|
|
|
|
|
* PERL_CONTEXT* - Pointer to the located context or NULL if not found. |
|
172
|
|
|
|
|
|
|
* |
|
173
|
|
|
|
|
|
|
* Description: |
|
174
|
|
|
|
|
|
|
* This searches up through the Perl call stack, accounting for DB::sub wrappers, |
|
175
|
|
|
|
|
|
|
* and returns the context frame corresponding to the requested call depth. |
|
176
|
|
|
|
|
|
|
* |
|
177
|
|
|
|
|
|
|
* Internal: |
|
178
|
|
|
|
|
|
|
* Used by want_gimme(), want_lvalue(), find_return_op(), and other context-inspection functions. |
|
179
|
|
|
|
|
|
|
*/ |
|
180
|
|
|
|
|
|
|
PERL_CONTEXT* |
|
181
|
1009
|
|
|
|
|
|
upcontext(pTHX_ I32 count) |
|
182
|
|
|
|
|
|
|
{ |
|
183
|
1009
|
|
|
|
|
|
PERL_SI *top_si = PL_curstackinfo; |
|
184
|
1009
|
|
|
|
|
|
I32 cxix = dopoptosub(aTHX_ cxstack_ix); |
|
185
|
|
|
|
|
|
|
PERL_CONTEXT *cx; |
|
186
|
1009
|
|
|
|
|
|
PERL_CONTEXT *ccstack = cxstack; |
|
187
|
|
|
|
|
|
|
I32 dbcxix; |
|
188
|
|
|
|
|
|
|
|
|
189
|
1009
|
50
|
|
|
|
|
if (!top_si || !ccstack || cxix < 0) |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
{ |
|
191
|
0
|
|
|
|
|
|
return (PERL_CONTEXT *)0; |
|
192
|
|
|
|
|
|
|
} |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
for (;;) |
|
195
|
|
|
|
|
|
|
{ |
|
196
|
4269
|
100
|
|
|
|
|
while (cxix < 0 && top_si->si_type != PERLSI_MAIN) |
|
|
|
50
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
{ |
|
198
|
0
|
|
|
|
|
|
top_si = top_si->si_prev; |
|
199
|
0
|
0
|
|
|
|
|
if (!top_si) |
|
200
|
|
|
|
|
|
|
{ |
|
201
|
0
|
|
|
|
|
|
return (PERL_CONTEXT *)0; |
|
202
|
|
|
|
|
|
|
} |
|
203
|
0
|
|
|
|
|
|
ccstack = top_si->si_cxstack; |
|
204
|
0
|
|
|
|
|
|
cxix = dopoptosub_at(aTHX_ ccstack, top_si->si_cxix); |
|
205
|
|
|
|
|
|
|
} |
|
206
|
4269
|
100
|
|
|
|
|
if (cxix < 0) |
|
207
|
|
|
|
|
|
|
{ |
|
208
|
5
|
|
|
|
|
|
return (PERL_CONTEXT *)0; |
|
209
|
|
|
|
|
|
|
} |
|
210
|
4264
|
50
|
|
|
|
|
if (PL_DBsub && cxix >= 0 && |
|
|
|
50
|
|
|
|
|
|
|
211
|
4264
|
50
|
|
|
|
|
ccstack[cxix].blk_sub.cv == GvCV(PL_DBsub)) |
|
212
|
0
|
|
|
|
|
|
count++; |
|
213
|
4264
|
100
|
|
|
|
|
if (!count--) |
|
214
|
1004
|
|
|
|
|
|
break; |
|
215
|
3260
|
|
|
|
|
|
cxix = dopoptosub_at(aTHX_ ccstack, cxix - 1); |
|
216
|
|
|
|
|
|
|
} |
|
217
|
1004
|
|
|
|
|
|
cx = &ccstack[cxix]; |
|
218
|
1004
|
50
|
|
|
|
|
if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) |
|
|
|
0
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
{ |
|
220
|
1004
|
|
|
|
|
|
dbcxix = dopoptosub_at(aTHX_ ccstack, cxix - 1); |
|
221
|
1004
|
50
|
|
|
|
|
if (PL_DBsub && dbcxix >= 0 && ccstack[dbcxix].blk_sub.cv == GvCV(PL_DBsub)) |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
{ |
|
223
|
0
|
|
|
|
|
|
cx = &ccstack[dbcxix]; |
|
224
|
|
|
|
|
|
|
} |
|
225
|
|
|
|
|
|
|
} |
|
226
|
1004
|
|
|
|
|
|
return cx; |
|
227
|
|
|
|
|
|
|
} |
|
228
|
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
/* |
|
230
|
|
|
|
|
|
|
* upcontext_plus - Retrieves the block or loop context enclosing the subroutine at the given depth. |
|
231
|
|
|
|
|
|
|
* |
|
232
|
|
|
|
|
|
|
* Arguments: |
|
233
|
|
|
|
|
|
|
* I32 count - Number of subroutine levels up to inspect. |
|
234
|
|
|
|
|
|
|
* bool end_of_block - Whether to return the context at the end of the enclosing block. |
|
235
|
|
|
|
|
|
|
* |
|
236
|
|
|
|
|
|
|
* Return: |
|
237
|
|
|
|
|
|
|
* PERL_CONTEXT* - The identified context or NULL. |
|
238
|
|
|
|
|
|
|
* |
|
239
|
|
|
|
|
|
|
* Description: |
|
240
|
|
|
|
|
|
|
* This is a more sophisticated version of 'upcontext', considering debugger issues, |
|
241
|
|
|
|
|
|
|
* tie/tied ops, and whether the block context is required instead of the sub context. |
|
242
|
|
|
|
|
|
|
* |
|
243
|
|
|
|
|
|
|
* Internal: |
|
244
|
|
|
|
|
|
|
* Used by find_start_cop() to locate the starting context op for a subroutine or block. |
|
245
|
|
|
|
|
|
|
*/ |
|
246
|
|
|
|
|
|
|
PERL_CONTEXT* |
|
247
|
728
|
|
|
|
|
|
upcontext_plus(pTHX_ I32 count, bool end_of_block) |
|
248
|
|
|
|
|
|
|
{ |
|
249
|
728
|
|
|
|
|
|
PERL_SI *top_si = PL_curstackinfo; |
|
250
|
728
|
|
|
|
|
|
I32 cxix = dopoptosub(aTHX_ cxstack_ix); |
|
251
|
|
|
|
|
|
|
PERL_CONTEXT *cx, *tcx; |
|
252
|
728
|
|
|
|
|
|
PERL_CONTEXT *ccstack = cxstack; |
|
253
|
|
|
|
|
|
|
I32 dbcxix, i; |
|
254
|
|
|
|
|
|
|
bool debugger_trouble; |
|
255
|
|
|
|
|
|
|
|
|
256
|
728
|
50
|
|
|
|
|
if (!top_si || !ccstack || cxix < 0) |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
{ |
|
258
|
0
|
|
|
|
|
|
return (PERL_CONTEXT *)0; |
|
259
|
|
|
|
|
|
|
} |
|
260
|
|
|
|
|
|
|
|
|
261
|
728
|
50
|
|
|
|
|
if (PL_op && (PL_op->op_type == OP_TIE || PL_op->op_type == OP_TIED)) |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
{ |
|
263
|
|
|
|
|
|
|
I32 i; |
|
264
|
0
|
0
|
|
|
|
|
for (i = cxix; i >= 0; i--) |
|
265
|
|
|
|
|
|
|
{ |
|
266
|
0
|
|
|
|
|
|
cx = &ccstack[i]; |
|
267
|
0
|
0
|
|
|
|
|
if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_BLOCK) |
|
|
|
0
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
{ |
|
269
|
0
|
0
|
|
|
|
|
OP *op = cx->blk_oldcop ? (OP*)cx->blk_oldcop : PL_op; |
|
270
|
0
|
0
|
|
|
|
|
if (op && (op->op_type == OP_LIST || op->op_type == OP_AASSIGN)) |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
{ |
|
272
|
0
|
|
|
|
|
|
cx->blk_gimme = G_ARRAY; |
|
273
|
|
|
|
|
|
|
} |
|
274
|
0
|
|
|
|
|
|
return cx; |
|
275
|
|
|
|
|
|
|
} |
|
276
|
|
|
|
|
|
|
} |
|
277
|
0
|
|
|
|
|
|
return (PERL_CONTEXT *)0; |
|
278
|
|
|
|
|
|
|
} |
|
279
|
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
for (;;) |
|
281
|
|
|
|
|
|
|
{ |
|
282
|
3480
|
100
|
|
|
|
|
while (cxix < 0 && top_si->si_type != PERLSI_MAIN) |
|
|
|
50
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
{ |
|
284
|
0
|
|
|
|
|
|
top_si = top_si->si_prev; |
|
285
|
0
|
0
|
|
|
|
|
if (!top_si) |
|
286
|
|
|
|
|
|
|
{ |
|
287
|
0
|
|
|
|
|
|
return (PERL_CONTEXT *)0; |
|
288
|
|
|
|
|
|
|
} |
|
289
|
0
|
|
|
|
|
|
ccstack = top_si->si_cxstack; |
|
290
|
0
|
|
|
|
|
|
cxix = dopoptosub_at(aTHX_ ccstack, top_si->si_cxix); |
|
291
|
|
|
|
|
|
|
} |
|
292
|
3480
|
100
|
|
|
|
|
if (cxix < 0) |
|
293
|
|
|
|
|
|
|
{ |
|
294
|
2
|
|
|
|
|
|
return (PERL_CONTEXT *)0; |
|
295
|
|
|
|
|
|
|
} |
|
296
|
3478
|
50
|
|
|
|
|
if (PL_DBsub && cxix >= 0 && |
|
|
|
50
|
|
|
|
|
|
|
297
|
3478
|
50
|
|
|
|
|
ccstack[cxix].blk_sub.cv == GvCV(PL_DBsub)) |
|
298
|
0
|
|
|
|
|
|
count++; |
|
299
|
3478
|
100
|
|
|
|
|
if (!count--) |
|
300
|
726
|
|
|
|
|
|
break; |
|
301
|
2752
|
|
|
|
|
|
cxix = dopoptosub_at(aTHX_ ccstack, cxix - 1); |
|
302
|
|
|
|
|
|
|
} |
|
303
|
726
|
|
|
|
|
|
cx = &ccstack[cxix]; |
|
304
|
726
|
50
|
|
|
|
|
if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) |
|
|
|
0
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
{ |
|
306
|
726
|
|
|
|
|
|
dbcxix = dopoptosub_at(aTHX_ ccstack, cxix - 1); |
|
307
|
726
|
50
|
|
|
|
|
if (PL_DBsub && dbcxix >= 0 && ccstack[dbcxix].blk_sub.cv == GvCV(PL_DBsub)) |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
{ |
|
309
|
0
|
|
|
|
|
|
cxix = dbcxix; |
|
310
|
0
|
|
|
|
|
|
cx = &ccstack[dbcxix]; |
|
311
|
|
|
|
|
|
|
} |
|
312
|
|
|
|
|
|
|
} |
|
313
|
|
|
|
|
|
|
|
|
314
|
726
|
|
|
|
|
|
debugger_trouble = (cx->blk_oldcop->op_type == OP_DBSTATE); |
|
315
|
|
|
|
|
|
|
|
|
316
|
1348
|
100
|
|
|
|
|
for (i = cxix-1; i>=0 ; i--) |
|
317
|
|
|
|
|
|
|
{ |
|
318
|
832
|
|
|
|
|
|
tcx = &ccstack[i]; |
|
319
|
832
|
|
|
|
|
|
switch (CxTYPE(tcx)) |
|
320
|
|
|
|
|
|
|
{ |
|
321
|
599
|
|
|
|
|
|
case CXt_BLOCK: |
|
322
|
599
|
50
|
|
|
|
|
if (debugger_trouble && i > 0) return tcx; |
|
|
|
0
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
default: |
|
324
|
622
|
|
|
|
|
|
continue; |
|
325
|
|
|
|
|
|
|
#ifdef CXt_LOOP_PLAIN |
|
326
|
114
|
|
|
|
|
|
case CXt_LOOP_PLAIN: |
|
327
|
|
|
|
|
|
|
#endif |
|
328
|
|
|
|
|
|
|
#ifdef CXt_LOOP_FOR |
|
329
|
|
|
|
|
|
|
case CXt_LOOP_FOR: |
|
330
|
|
|
|
|
|
|
#endif |
|
331
|
|
|
|
|
|
|
#ifdef CXt_LOOP_LIST |
|
332
|
|
|
|
|
|
|
case CXt_LOOP_LIST: |
|
333
|
|
|
|
|
|
|
#endif |
|
334
|
|
|
|
|
|
|
#ifdef CXt_LOOP_ARY |
|
335
|
|
|
|
|
|
|
case CXt_LOOP_ARY: |
|
336
|
|
|
|
|
|
|
#endif |
|
337
|
|
|
|
|
|
|
#ifdef CXt_LOOP |
|
338
|
|
|
|
|
|
|
case CXt_LOOP: |
|
339
|
|
|
|
|
|
|
#endif |
|
340
|
114
|
|
|
|
|
|
return tcx; |
|
341
|
96
|
|
|
|
|
|
case CXt_SUB: |
|
342
|
|
|
|
|
|
|
case CXt_FORMAT: |
|
343
|
96
|
|
|
|
|
|
return cx; |
|
344
|
|
|
|
|
|
|
} |
|
345
|
|
|
|
|
|
|
} |
|
346
|
516
|
100
|
|
|
|
|
return ((end_of_block && cxix > 1) ? &ccstack[cxix-1] : cx); |
|
|
|
50
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
} |
|
348
|
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
/* |
|
350
|
|
|
|
|
|
|
* want_gimme - Returns the context type (void, scalar, or array) at the given call stack level. |
|
351
|
|
|
|
|
|
|
* |
|
352
|
|
|
|
|
|
|
* Arguments: |
|
353
|
|
|
|
|
|
|
* I32 uplevel - The number of call frames up to check. |
|
354
|
|
|
|
|
|
|
* |
|
355
|
|
|
|
|
|
|
* Return: |
|
356
|
|
|
|
|
|
|
* U8 - One of G_VOID, G_SCALAR, or G_ARRAY. |
|
357
|
|
|
|
|
|
|
* |
|
358
|
|
|
|
|
|
|
* Description: |
|
359
|
|
|
|
|
|
|
* This uses the PERL_CONTEXT retrieved by 'upcontext' to determine the evaluation context |
|
360
|
|
|
|
|
|
|
* of the caller. It is a low-level helper for functions like wantarray_up(). |
|
361
|
|
|
|
|
|
|
* |
|
362
|
|
|
|
|
|
|
* Internal: |
|
363
|
|
|
|
|
|
|
* Used by wantarray_up(), want_count(), and Perl-side context inspection. |
|
364
|
|
|
|
|
|
|
*/ |
|
365
|
|
|
|
|
|
|
U8 |
|
366
|
96
|
|
|
|
|
|
want_gimme (I32 uplevel) |
|
367
|
|
|
|
|
|
|
{ |
|
368
|
96
|
|
|
|
|
|
PERL_CONTEXT* cx = upcontext(aTHX_ uplevel); |
|
369
|
96
|
100
|
|
|
|
|
if (!cx) return G_VOID; |
|
370
|
95
|
|
|
|
|
|
return cx->blk_gimme; |
|
371
|
|
|
|
|
|
|
} |
|
372
|
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
/* |
|
374
|
|
|
|
|
|
|
* lastnumop - Retrieves the last meaningful 'numop' from an 'oplist'. |
|
375
|
|
|
|
|
|
|
* |
|
376
|
|
|
|
|
|
|
* Arguments: |
|
377
|
|
|
|
|
|
|
* oplist* l - Pointer to an 'oplist' structure containing a sequence of 'numop' entries. |
|
378
|
|
|
|
|
|
|
* |
|
379
|
|
|
|
|
|
|
* Return: |
|
380
|
|
|
|
|
|
|
* numop* - A pointer to the last 'numop' whose op is not of type 'OP_NULL' or 'OP_SCOPE', |
|
381
|
|
|
|
|
|
|
* or NULL if no such entry exists. |
|
382
|
|
|
|
|
|
|
* |
|
383
|
|
|
|
|
|
|
* Description: |
|
384
|
|
|
|
|
|
|
* This function scans backward through the list of 'numop' entries and returns the last |
|
385
|
|
|
|
|
|
|
* one that corresponds to a significant operation. It is used to find the operative |
|
386
|
|
|
|
|
|
|
* instruction before a return or assignment analysis. |
|
387
|
|
|
|
|
|
|
* |
|
388
|
|
|
|
|
|
|
* Internal: |
|
389
|
|
|
|
|
|
|
* Used by 'want_assign()' to determine the final operational node before returning values. |
|
390
|
|
|
|
|
|
|
*/ |
|
391
|
|
|
|
|
|
|
numop* |
|
392
|
23
|
|
|
|
|
|
lastnumop(oplist* l) |
|
393
|
|
|
|
|
|
|
{ |
|
394
|
|
|
|
|
|
|
U16 i; |
|
395
|
|
|
|
|
|
|
numop* ret; |
|
396
|
|
|
|
|
|
|
|
|
397
|
23
|
50
|
|
|
|
|
if (!l) return (numop*)0; |
|
398
|
23
|
|
|
|
|
|
i = l->length; |
|
399
|
25
|
50
|
|
|
|
|
while (i-- > 0) |
|
400
|
|
|
|
|
|
|
{ |
|
401
|
25
|
|
|
|
|
|
ret = &(l->ops)[i]; |
|
402
|
25
|
100
|
|
|
|
|
if (ret->numop_op->op_type != OP_NULL && ret->numop_op->op_type != OP_SCOPE) |
|
|
|
50
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
{ |
|
404
|
23
|
|
|
|
|
|
return ret; |
|
405
|
|
|
|
|
|
|
} |
|
406
|
|
|
|
|
|
|
} |
|
407
|
0
|
|
|
|
|
|
return (numop*)0; |
|
408
|
|
|
|
|
|
|
} |
|
409
|
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
/* |
|
411
|
|
|
|
|
|
|
* lastop - Returns the last significant OP from a given oplist. |
|
412
|
|
|
|
|
|
|
* |
|
413
|
|
|
|
|
|
|
* Arguments: |
|
414
|
|
|
|
|
|
|
* oplist* l - The list of operations to search. |
|
415
|
|
|
|
|
|
|
* |
|
416
|
|
|
|
|
|
|
* Return: |
|
417
|
|
|
|
|
|
|
* OP* - The last non-NULL, non-SCOPE, non-LEAVE op, or Nullop if none found. |
|
418
|
|
|
|
|
|
|
* |
|
419
|
|
|
|
|
|
|
* Description: |
|
420
|
|
|
|
|
|
|
* This function scans backwards through an oplist to find the last significant operation, |
|
421
|
|
|
|
|
|
|
* ignoring NULL, SCOPE, and LEAVE ops. It is used to determine the most relevant op at |
|
422
|
|
|
|
|
|
|
* the end of an op chain, typically for context or assignment analysis. |
|
423
|
|
|
|
|
|
|
* |
|
424
|
|
|
|
|
|
|
* Internal: |
|
425
|
|
|
|
|
|
|
* Used by parent_op() to identify the final operation in an op chain. |
|
426
|
|
|
|
|
|
|
*/ |
|
427
|
|
|
|
|
|
|
OP* |
|
428
|
632
|
|
|
|
|
|
lastop(oplist* l) |
|
429
|
|
|
|
|
|
|
{ |
|
430
|
|
|
|
|
|
|
U16 i; |
|
431
|
|
|
|
|
|
|
OP* ret; |
|
432
|
|
|
|
|
|
|
|
|
433
|
632
|
100
|
|
|
|
|
if (!l) return Nullop; |
|
434
|
565
|
|
|
|
|
|
i = l->length; |
|
435
|
834
|
100
|
|
|
|
|
while (i-- > 0) |
|
436
|
|
|
|
|
|
|
{ |
|
437
|
779
|
|
|
|
|
|
ret = (l->ops)[i].numop_op; |
|
438
|
779
|
100
|
|
|
|
|
if (ret->op_type != OP_NULL |
|
439
|
599
|
50
|
|
|
|
|
&& ret->op_type != OP_SCOPE |
|
440
|
599
|
100
|
|
|
|
|
&& ret->op_type != OP_LEAVE) |
|
441
|
|
|
|
|
|
|
{ |
|
442
|
510
|
|
|
|
|
|
return ret; |
|
443
|
|
|
|
|
|
|
} |
|
444
|
|
|
|
|
|
|
} |
|
445
|
55
|
|
|
|
|
|
free(l); |
|
446
|
55
|
|
|
|
|
|
return Nullop; |
|
447
|
|
|
|
|
|
|
} |
|
448
|
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
/* |
|
450
|
|
|
|
|
|
|
* pushop - Adds an operation to an oplist with an associated index. |
|
451
|
|
|
|
|
|
|
* |
|
452
|
|
|
|
|
|
|
* Arguments: |
|
453
|
|
|
|
|
|
|
* oplist* l - The oplist to modify. |
|
454
|
|
|
|
|
|
|
* OP* o - The op to push. |
|
455
|
|
|
|
|
|
|
* U16 i - The op’s index or position. |
|
456
|
|
|
|
|
|
|
* |
|
457
|
|
|
|
|
|
|
* Return: |
|
458
|
|
|
|
|
|
|
* oplist* - The modified list. |
|
459
|
|
|
|
|
|
|
* |
|
460
|
|
|
|
|
|
|
* Description: |
|
461
|
|
|
|
|
|
|
* This utility is used during op tree traversal to maintain a list of encountered operations. |
|
462
|
|
|
|
|
|
|
* |
|
463
|
|
|
|
|
|
|
* Internal: |
|
464
|
|
|
|
|
|
|
* Used by find_ancestors_from() to build the list of parent ops. |
|
465
|
|
|
|
|
|
|
*/ |
|
466
|
|
|
|
|
|
|
oplist* |
|
467
|
2833
|
|
|
|
|
|
pushop(oplist* l, OP* o, U16 i) |
|
468
|
|
|
|
|
|
|
{ |
|
469
|
2833
|
|
|
|
|
|
I16 len = l->length; |
|
470
|
2833
|
100
|
|
|
|
|
if (o && len < OPLIST_MAX) |
|
|
|
50
|
|
|
|
|
|
|
471
|
|
|
|
|
|
|
{ |
|
472
|
2177
|
|
|
|
|
|
++ l->length; |
|
473
|
2177
|
|
|
|
|
|
l->ops[len].numop_op = o; |
|
474
|
2177
|
|
|
|
|
|
l->ops[len].numop_num = -1; |
|
475
|
|
|
|
|
|
|
} |
|
476
|
2833
|
100
|
|
|
|
|
if (len > 0) |
|
477
|
2177
|
|
|
|
|
|
l->ops[len-1].numop_num = i; |
|
478
|
|
|
|
|
|
|
|
|
479
|
2833
|
|
|
|
|
|
return l; |
|
480
|
|
|
|
|
|
|
} |
|
481
|
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
/* |
|
483
|
|
|
|
|
|
|
* find_ancestors_from - Recursively traverses an op tree to find a path to a target op. |
|
484
|
|
|
|
|
|
|
* |
|
485
|
|
|
|
|
|
|
* Arguments: |
|
486
|
|
|
|
|
|
|
* OP* start - Starting op for the tree walk. |
|
487
|
|
|
|
|
|
|
* OP* next - Target op to find. |
|
488
|
|
|
|
|
|
|
* oplist* l - The oplist to accumulate ops into (can be NULL). |
|
489
|
|
|
|
|
|
|
* |
|
490
|
|
|
|
|
|
|
* Return: |
|
491
|
|
|
|
|
|
|
* oplist* - A list of parent ops leading to the target op, or NULL if not found. |
|
492
|
|
|
|
|
|
|
* |
|
493
|
|
|
|
|
|
|
* Description: |
|
494
|
|
|
|
|
|
|
* This function recursively traverses the op tree starting from 'start' to find a path |
|
495
|
|
|
|
|
|
|
* to the 'next' op, accumulating parent ops in an oplist. It is used to trace a path |
|
496
|
|
|
|
|
|
|
* through the abstract syntax tree (AST) from a COP to a return op. |
|
497
|
|
|
|
|
|
|
* |
|
498
|
|
|
|
|
|
|
* Notes: |
|
499
|
|
|
|
|
|
|
* The caller is responsible for freeing the oplist if the function returns NULL. |
|
500
|
|
|
|
|
|
|
* |
|
501
|
|
|
|
|
|
|
* Internal: |
|
502
|
|
|
|
|
|
|
* Used by ancestor_ops() to build the list of ancestor ops for context analysis. |
|
503
|
|
|
|
|
|
|
*/ |
|
504
|
|
|
|
|
|
|
oplist* |
|
505
|
2833
|
|
|
|
|
|
find_ancestors_from(OP* start, OP* next, oplist* l) |
|
506
|
|
|
|
|
|
|
{ |
|
507
|
|
|
|
|
|
|
OP *o, *p; |
|
508
|
2833
|
|
|
|
|
|
U16 cn = 0; |
|
509
|
|
|
|
|
|
|
U16 ll; |
|
510
|
2833
|
|
|
|
|
|
bool outer_call = FALSE; |
|
511
|
|
|
|
|
|
|
|
|
512
|
2833
|
50
|
|
|
|
|
if (!start || !next) |
|
|
|
50
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
{ |
|
514
|
|
|
|
|
|
|
/* Do not free l here; let the caller handle it */ |
|
515
|
0
|
|
|
|
|
|
return (oplist*)0; |
|
516
|
|
|
|
|
|
|
} |
|
517
|
|
|
|
|
|
|
|
|
518
|
2833
|
100
|
|
|
|
|
if (!l) |
|
519
|
|
|
|
|
|
|
{ |
|
520
|
656
|
|
|
|
|
|
outer_call = TRUE; |
|
521
|
656
|
|
|
|
|
|
l = new_oplist; |
|
522
|
656
|
|
|
|
|
|
init_oplist(l); |
|
523
|
656
|
|
|
|
|
|
ll = 0; |
|
524
|
|
|
|
|
|
|
} |
|
525
|
2177
|
|
|
|
|
|
else ll = l->length; |
|
526
|
|
|
|
|
|
|
|
|
527
|
5432
|
100
|
|
|
|
|
for (o = start; o; p = o, o = OpSIBLING(o), ++cn) |
|
|
|
100
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
{ |
|
529
|
4839
|
100
|
|
|
|
|
if (o->op_type == OP_ENTERSUB && o->op_next == next) |
|
|
|
100
|
|
|
|
|
|
|
530
|
656
|
|
|
|
|
|
return pushop(l, Nullop, cn); |
|
531
|
|
|
|
|
|
|
|
|
532
|
4183
|
100
|
|
|
|
|
if (o->op_flags & OPf_KIDS) |
|
533
|
|
|
|
|
|
|
{ |
|
534
|
2177
|
|
|
|
|
|
U16 ll = l->length; |
|
535
|
|
|
|
|
|
|
|
|
536
|
2177
|
|
|
|
|
|
pushop(l, o, cn); |
|
537
|
2177
|
100
|
|
|
|
|
if (find_ancestors_from(cUNOPo->op_first, next, l)) |
|
538
|
1584
|
|
|
|
|
|
return l; |
|
539
|
|
|
|
|
|
|
else |
|
540
|
593
|
|
|
|
|
|
l->length = ll; |
|
541
|
|
|
|
|
|
|
} |
|
542
|
|
|
|
|
|
|
} |
|
543
|
|
|
|
|
|
|
/* Do not free l here; let the caller handle it */ |
|
544
|
593
|
|
|
|
|
|
return (oplist*)0; |
|
545
|
|
|
|
|
|
|
} |
|
546
|
|
|
|
|
|
|
|
|
547
|
|
|
|
|
|
|
/* |
|
548
|
|
|
|
|
|
|
* find_return_op - Resolves the return OP for the subroutine at a given depth. |
|
549
|
|
|
|
|
|
|
* |
|
550
|
|
|
|
|
|
|
* Arguments: |
|
551
|
|
|
|
|
|
|
* I32 uplevel - The number of frames up to inspect. |
|
552
|
|
|
|
|
|
|
* |
|
553
|
|
|
|
|
|
|
* Return: |
|
554
|
|
|
|
|
|
|
* OP* - The op that is used to return from the subroutine, or Nullop if not found. |
|
555
|
|
|
|
|
|
|
* |
|
556
|
|
|
|
|
|
|
* Description: |
|
557
|
|
|
|
|
|
|
* This inspects the current cxstack or PL_retstack to find the return point for a sub. |
|
558
|
|
|
|
|
|
|
* |
|
559
|
|
|
|
|
|
|
* Internal: |
|
560
|
|
|
|
|
|
|
* Used by ancestor_ops() to determine the return op for context analysis. |
|
561
|
|
|
|
|
|
|
*/ |
|
562
|
|
|
|
|
|
|
OP* |
|
563
|
728
|
|
|
|
|
|
find_return_op(pTHX_ I32 uplevel) |
|
564
|
|
|
|
|
|
|
{ |
|
565
|
728
|
|
|
|
|
|
PERL_CONTEXT *cx = upcontext(aTHX_ uplevel); |
|
566
|
728
|
100
|
|
|
|
|
if (!cx) |
|
567
|
|
|
|
|
|
|
{ |
|
568
|
2
|
|
|
|
|
|
return Nullop; |
|
569
|
|
|
|
|
|
|
} |
|
570
|
|
|
|
|
|
|
#if HAS_RETSTACK |
|
571
|
|
|
|
|
|
|
return PL_retstack[cx->blk_oldretsp - 1]; |
|
572
|
|
|
|
|
|
|
#else |
|
573
|
726
|
|
|
|
|
|
return cx->blk_sub.retop; |
|
574
|
|
|
|
|
|
|
#endif |
|
575
|
|
|
|
|
|
|
} |
|
576
|
|
|
|
|
|
|
|
|
577
|
|
|
|
|
|
|
/* |
|
578
|
|
|
|
|
|
|
* find_start_cop - Returns the start COP (context op) for the subroutine frame. |
|
579
|
|
|
|
|
|
|
* |
|
580
|
|
|
|
|
|
|
* Arguments: |
|
581
|
|
|
|
|
|
|
* I32 uplevel - Call stack depth to inspect. |
|
582
|
|
|
|
|
|
|
* bool end_of_block - If true, return the enclosing block cop. |
|
583
|
|
|
|
|
|
|
* |
|
584
|
|
|
|
|
|
|
* Return: |
|
585
|
|
|
|
|
|
|
* OP* - The starting COP for the sub or block context, or Nullop if not found. |
|
586
|
|
|
|
|
|
|
* |
|
587
|
|
|
|
|
|
|
* Description: |
|
588
|
|
|
|
|
|
|
* This function determines the starting COP (context op) for a subroutine or block |
|
589
|
|
|
|
|
|
|
* at the specified call stack depth, helping to identify where execution begins. |
|
590
|
|
|
|
|
|
|
* |
|
591
|
|
|
|
|
|
|
* Internal: |
|
592
|
|
|
|
|
|
|
* Used by ancestor_ops() to find the starting point for op tree traversal. |
|
593
|
|
|
|
|
|
|
*/ |
|
594
|
|
|
|
|
|
|
OP* |
|
595
|
728
|
|
|
|
|
|
find_start_cop(pTHX_ I32 uplevel, bool end_of_block) |
|
596
|
|
|
|
|
|
|
{ |
|
597
|
728
|
|
|
|
|
|
PERL_CONTEXT* cx = upcontext_plus(aTHX_ uplevel, end_of_block); |
|
598
|
728
|
100
|
|
|
|
|
if (!cx) |
|
599
|
|
|
|
|
|
|
{ |
|
600
|
2
|
|
|
|
|
|
return Nullop; |
|
601
|
|
|
|
|
|
|
} |
|
602
|
726
|
|
|
|
|
|
return (OP*) cx->blk_oldcop; |
|
603
|
|
|
|
|
|
|
} |
|
604
|
|
|
|
|
|
|
|
|
605
|
|
|
|
|
|
|
/* |
|
606
|
|
|
|
|
|
|
* ancestor_ops - Produces a list of ancestor ops from sub start to return. |
|
607
|
|
|
|
|
|
|
* |
|
608
|
|
|
|
|
|
|
* Arguments: |
|
609
|
|
|
|
|
|
|
* I32 uplevel - Stack level to inspect. |
|
610
|
|
|
|
|
|
|
* OP** return_op_out - Optional pointer to capture return op. |
|
611
|
|
|
|
|
|
|
* |
|
612
|
|
|
|
|
|
|
* Return: |
|
613
|
|
|
|
|
|
|
* oplist* - A list of operations between sub entry and return, or NULL if not found. |
|
614
|
|
|
|
|
|
|
* |
|
615
|
|
|
|
|
|
|
* Description: |
|
616
|
|
|
|
|
|
|
* This function walks the op tree using 'find_start_cop' and 'find_return_op', |
|
617
|
|
|
|
|
|
|
* storing the trace path in an oplist. It is used to analyse the operations |
|
618
|
|
|
|
|
|
|
* between a subroutine's entry and return points. |
|
619
|
|
|
|
|
|
|
* |
|
620
|
|
|
|
|
|
|
* Notes: |
|
621
|
|
|
|
|
|
|
* The caller is responsible for freeing the returned oplist. |
|
622
|
|
|
|
|
|
|
* |
|
623
|
|
|
|
|
|
|
* Internal: |
|
624
|
|
|
|
|
|
|
* Used by want_boolean() and want_assign() for context analysis. |
|
625
|
|
|
|
|
|
|
*/ |
|
626
|
|
|
|
|
|
|
oplist* |
|
627
|
728
|
|
|
|
|
|
ancestor_ops (I32 uplevel, OP** return_op_out) |
|
628
|
|
|
|
|
|
|
{ |
|
629
|
728
|
|
|
|
|
|
OP* return_op = find_return_op(aTHX_ uplevel); |
|
630
|
728
|
|
|
|
|
|
OP* start_cop = find_start_cop(aTHX_ uplevel, |
|
631
|
728
|
100
|
|
|
|
|
return_op ? return_op->op_type == OP_LEAVE : FALSE); |
|
|
|
100
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
|
|
633
|
728
|
100
|
|
|
|
|
if (!return_op || !start_cop) |
|
|
|
50
|
|
|
|
|
|
|
634
|
|
|
|
|
|
|
{ |
|
635
|
72
|
100
|
|
|
|
|
if (return_op_out) *return_op_out = Nullop; |
|
636
|
72
|
|
|
|
|
|
return (oplist*)0; |
|
637
|
|
|
|
|
|
|
} |
|
638
|
|
|
|
|
|
|
|
|
639
|
656
|
100
|
|
|
|
|
if (return_op_out) |
|
640
|
588
|
|
|
|
|
|
*return_op_out = return_op; |
|
641
|
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
/* return find_ancestors_from(start_cop, return_op, 0); */ |
|
643
|
656
|
|
|
|
|
|
oplist* result = find_ancestors_from(start_cop, return_op, 0); |
|
644
|
656
|
50
|
|
|
|
|
if (!result) |
|
645
|
|
|
|
|
|
|
{ |
|
646
|
|
|
|
|
|
|
/* Free the oplist if find_ancestors_from allocated it but failed */ |
|
647
|
0
|
|
|
|
|
|
free(result); // This will be a no-op since result is NULL |
|
648
|
0
|
|
|
|
|
|
return (oplist*)0; |
|
649
|
|
|
|
|
|
|
} |
|
650
|
656
|
|
|
|
|
|
return result; |
|
651
|
|
|
|
|
|
|
} |
|
652
|
|
|
|
|
|
|
|
|
653
|
|
|
|
|
|
|
/* |
|
654
|
|
|
|
|
|
|
* parent_op - Retrieves the parent OP of the current OP in the call stack. |
|
655
|
|
|
|
|
|
|
* |
|
656
|
|
|
|
|
|
|
* Arguments: |
|
657
|
|
|
|
|
|
|
* I32 uplevel - Stack level to begin inspection. |
|
658
|
|
|
|
|
|
|
* OP **retop - A pointer to receive the resolved OP. |
|
659
|
|
|
|
|
|
|
* |
|
660
|
|
|
|
|
|
|
* Return: |
|
661
|
|
|
|
|
|
|
* OP* - The parent operation at the given level. |
|
662
|
|
|
|
|
|
|
* |
|
663
|
|
|
|
|
|
|
* Description: |
|
664
|
|
|
|
|
|
|
* This walks the OP tree upward from the caller’s stack frame to find the relevant parent. |
|
665
|
|
|
|
|
|
|
* |
|
666
|
|
|
|
|
|
|
* Internal: |
|
667
|
|
|
|
|
|
|
* Used by parent_op_name() and first_multideref_type(). |
|
668
|
|
|
|
|
|
|
*/ |
|
669
|
|
|
|
|
|
|
OP* |
|
670
|
632
|
|
|
|
|
|
parent_op (I32 uplevel, OP** return_op_out) |
|
671
|
|
|
|
|
|
|
{ |
|
672
|
632
|
|
|
|
|
|
return lastop(ancestor_ops(uplevel, return_op_out)); |
|
673
|
|
|
|
|
|
|
} |
|
674
|
|
|
|
|
|
|
|
|
675
|
|
|
|
|
|
|
/* |
|
676
|
|
|
|
|
|
|
* count_slice - Calculates the number of elements in a slice op. |
|
677
|
|
|
|
|
|
|
* |
|
678
|
|
|
|
|
|
|
* Arguments: |
|
679
|
|
|
|
|
|
|
* OP* o - The slice op (e.g., OP_HSLICE or OP_ASLICE). |
|
680
|
|
|
|
|
|
|
* |
|
681
|
|
|
|
|
|
|
* Return: |
|
682
|
|
|
|
|
|
|
* I32 - The number of elements being sliced, or -999 on error. |
|
683
|
|
|
|
|
|
|
* |
|
684
|
|
|
|
|
|
|
* Description: |
|
685
|
|
|
|
|
|
|
* Recursively walks the op tree to count list elements involved in slicing, |
|
686
|
|
|
|
|
|
|
* such as in array or hash slice operations. |
|
687
|
|
|
|
|
|
|
* |
|
688
|
|
|
|
|
|
|
* Internal: |
|
689
|
|
|
|
|
|
|
* Used by count_list() to determine the size of sliced elements in assignments. |
|
690
|
|
|
|
|
|
|
*/ |
|
691
|
|
|
|
|
|
|
I32 |
|
692
|
9
|
|
|
|
|
|
count_slice (OP* o) |
|
693
|
|
|
|
|
|
|
{ |
|
694
|
|
|
|
|
|
|
OP* pm; |
|
695
|
9
|
|
|
|
|
|
OP* l = Nullop; |
|
696
|
|
|
|
|
|
|
|
|
697
|
9
|
50
|
|
|
|
|
if (!o) return -999; |
|
698
|
9
|
|
|
|
|
|
pm = cUNOPo->op_first; |
|
699
|
9
|
50
|
|
|
|
|
if (!pm || pm->op_type != OP_PUSHMARK) |
|
|
|
50
|
|
|
|
|
|
|
700
|
0
|
|
|
|
|
|
die("%s", "Wanted panicked: slice doesn't start with pushmark\n"); |
|
701
|
|
|
|
|
|
|
|
|
702
|
9
|
50
|
|
|
|
|
if ( (l = OpSIBLING(pm)) && (l->op_type == OP_LIST || (l->op_type == OP_NULL && l->op_targ == OP_LIST))) |
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
703
|
4
|
|
|
|
|
|
return count_list(l, Nullop); |
|
704
|
|
|
|
|
|
|
|
|
705
|
5
|
50
|
|
|
|
|
else if (l) |
|
706
|
5
|
|
|
|
|
|
switch (l->op_type) |
|
707
|
|
|
|
|
|
|
{ |
|
708
|
1
|
|
|
|
|
|
case OP_RV2AV: |
|
709
|
|
|
|
|
|
|
case OP_PADAV: |
|
710
|
|
|
|
|
|
|
case OP_PADHV: |
|
711
|
|
|
|
|
|
|
case OP_RV2HV: |
|
712
|
1
|
|
|
|
|
|
return 0; |
|
713
|
2
|
|
|
|
|
|
case OP_HSLICE: |
|
714
|
|
|
|
|
|
|
case OP_ASLICE: |
|
715
|
2
|
|
|
|
|
|
return count_slice(l); |
|
716
|
2
|
|
|
|
|
|
case OP_STUB: |
|
717
|
2
|
|
|
|
|
|
return 1; |
|
718
|
0
|
|
|
|
|
|
default: |
|
719
|
0
|
|
|
|
|
|
die("Wanted panicked: Unexpected op in slice (%s)\n", PL_op_name[l->op_type]); |
|
720
|
|
|
|
|
|
|
} |
|
721
|
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
else |
|
723
|
0
|
|
|
|
|
|
die("Wanted panicked: Nothing follows pushmark in slice\n"); |
|
724
|
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
return -999; |
|
726
|
|
|
|
|
|
|
} |
|
727
|
|
|
|
|
|
|
|
|
728
|
|
|
|
|
|
|
/* |
|
729
|
|
|
|
|
|
|
* count_list - Counts the number of elements in a list op. |
|
730
|
|
|
|
|
|
|
* |
|
731
|
|
|
|
|
|
|
* Arguments: |
|
732
|
|
|
|
|
|
|
* OP* parent - The parent list op. |
|
733
|
|
|
|
|
|
|
* OP* returnop - Optional terminator to stop early. |
|
734
|
|
|
|
|
|
|
* |
|
735
|
|
|
|
|
|
|
* Return: |
|
736
|
|
|
|
|
|
|
* I32 - The number of child ops, or 0 if none. |
|
737
|
|
|
|
|
|
|
* |
|
738
|
|
|
|
|
|
|
* Description: |
|
739
|
|
|
|
|
|
|
* This function counts the number of child ops in a list op, helping to determine |
|
740
|
|
|
|
|
|
|
* the number of left-hand-side variables in assignments (e.g., my( $a, $b ) = ...). |
|
741
|
|
|
|
|
|
|
* |
|
742
|
|
|
|
|
|
|
* Internal: |
|
743
|
|
|
|
|
|
|
* Used by want_count() and want_assign() for assignment analysis. |
|
744
|
|
|
|
|
|
|
*/ |
|
745
|
|
|
|
|
|
|
I32 |
|
746
|
39
|
|
|
|
|
|
count_list (OP* parent, OP* returnop) |
|
747
|
|
|
|
|
|
|
{ |
|
748
|
|
|
|
|
|
|
OP* o; |
|
749
|
39
|
|
|
|
|
|
I32 i = 0; |
|
750
|
|
|
|
|
|
|
|
|
751
|
39
|
50
|
|
|
|
|
if (!parent || ! (parent->op_flags & OPf_KIDS)) |
|
|
|
50
|
|
|
|
|
|
|
752
|
0
|
|
|
|
|
|
return 0; |
|
753
|
|
|
|
|
|
|
|
|
754
|
117
|
100
|
|
|
|
|
for(o = cUNOPx(parent)->op_first; o; o=OpSIBLING(o)) |
|
|
|
100
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
{ |
|
756
|
96
|
50
|
|
|
|
|
if (returnop && o->op_type == OP_ENTERSUB && o->op_next == returnop) |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
757
|
0
|
|
|
|
|
|
return i; |
|
758
|
96
|
100
|
|
|
|
|
if (o->op_type == OP_RV2AV || o->op_type == OP_RV2HV |
|
|
|
100
|
|
|
|
|
|
|
759
|
90
|
100
|
|
|
|
|
|| o->op_type == OP_PADAV || o->op_type == OP_PADHV |
|
|
|
100
|
|
|
|
|
|
|
760
|
79
|
50
|
|
|
|
|
|| o->op_type == OP_ENTERSUB) |
|
761
|
17
|
|
|
|
|
|
return 0; |
|
762
|
|
|
|
|
|
|
|
|
763
|
79
|
100
|
|
|
|
|
if (o->op_type == OP_HSLICE || o->op_type == OP_ASLICE) |
|
|
|
100
|
|
|
|
|
|
|
764
|
6
|
|
|
|
|
|
{ |
|
765
|
7
|
|
|
|
|
|
I32 slice_length = count_slice(o); |
|
766
|
7
|
100
|
|
|
|
|
if (slice_length == 0) |
|
767
|
1
|
|
|
|
|
|
return 0; |
|
768
|
|
|
|
|
|
|
else |
|
769
|
6
|
|
|
|
|
|
i += slice_length - 1; |
|
770
|
|
|
|
|
|
|
} |
|
771
|
72
|
|
|
|
|
|
else ++i; |
|
772
|
|
|
|
|
|
|
} |
|
773
|
|
|
|
|
|
|
|
|
774
|
21
|
|
|
|
|
|
return i; |
|
775
|
|
|
|
|
|
|
} |
|
776
|
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
/* |
|
778
|
|
|
|
|
|
|
* countstack - Counts the number of stack values passed to a subroutine. |
|
779
|
|
|
|
|
|
|
* |
|
780
|
|
|
|
|
|
|
* Arguments: |
|
781
|
|
|
|
|
|
|
* I32 uplevel - Stack frame level to inspect. |
|
782
|
|
|
|
|
|
|
* |
|
783
|
|
|
|
|
|
|
* Return: |
|
784
|
|
|
|
|
|
|
* I32 - Number of items between oldmarksp and current mark, or -1 if context not found. |
|
785
|
|
|
|
|
|
|
* |
|
786
|
|
|
|
|
|
|
* Description: |
|
787
|
|
|
|
|
|
|
* This function counts the number of values on the stack between the old mark and |
|
788
|
|
|
|
|
|
|
* the current mark, used to estimate how many right-hand-side values exist in an assignment. |
|
789
|
|
|
|
|
|
|
* |
|
790
|
|
|
|
|
|
|
* Internal: |
|
791
|
|
|
|
|
|
|
* Used by want_count() to analyse assignment contexts. |
|
792
|
|
|
|
|
|
|
*/ |
|
793
|
|
|
|
|
|
|
I32 |
|
794
|
35
|
|
|
|
|
|
countstack(I32 uplevel) |
|
795
|
|
|
|
|
|
|
{ |
|
796
|
35
|
|
|
|
|
|
PERL_CONTEXT* cx = upcontext(aTHX_ uplevel); |
|
797
|
|
|
|
|
|
|
I32 oldmarksp; |
|
798
|
|
|
|
|
|
|
I32 mark_from; |
|
799
|
|
|
|
|
|
|
I32 mark_to; |
|
800
|
|
|
|
|
|
|
|
|
801
|
35
|
50
|
|
|
|
|
if (!cx) return -1; |
|
802
|
|
|
|
|
|
|
|
|
803
|
35
|
|
|
|
|
|
oldmarksp = cx->blk_oldmarksp; |
|
804
|
35
|
|
|
|
|
|
mark_from = PL_markstack[oldmarksp]; |
|
805
|
35
|
|
|
|
|
|
mark_to = PL_markstack[oldmarksp+1]; |
|
806
|
35
|
|
|
|
|
|
return (mark_to - mark_from); |
|
807
|
|
|
|
|
|
|
} |
|
808
|
|
|
|
|
|
|
|
|
809
|
|
|
|
|
|
|
/* |
|
810
|
|
|
|
|
|
|
* copy_rvals - Returns an array of stack values passed to a subroutine. |
|
811
|
|
|
|
|
|
|
* |
|
812
|
|
|
|
|
|
|
* Arguments: |
|
813
|
|
|
|
|
|
|
* I32 uplevel - Stack level to inspect. |
|
814
|
|
|
|
|
|
|
* I32 skip - Number of items to skip from the start. |
|
815
|
|
|
|
|
|
|
* |
|
816
|
|
|
|
|
|
|
* Return: |
|
817
|
|
|
|
|
|
|
* AV* - An array of values beyond the 'skip' threshold, or Nullav if context not found. |
|
818
|
|
|
|
|
|
|
* |
|
819
|
|
|
|
|
|
|
* Description: |
|
820
|
|
|
|
|
|
|
* This copies the right-hand-side values passed to an assignment into an AV for Perl-side use. |
|
821
|
|
|
|
|
|
|
* |
|
822
|
|
|
|
|
|
|
* Internal: |
|
823
|
|
|
|
|
|
|
* Used by want_assign() to retrieve assignment values. |
|
824
|
|
|
|
|
|
|
*/ |
|
825
|
|
|
|
|
|
|
AV* |
|
826
|
0
|
|
|
|
|
|
copy_rvals(I32 uplevel, I32 skip) |
|
827
|
|
|
|
|
|
|
{ |
|
828
|
0
|
|
|
|
|
|
PERL_CONTEXT* cx = upcontext(aTHX_ uplevel); |
|
829
|
|
|
|
|
|
|
I32 oldmarksp; |
|
830
|
|
|
|
|
|
|
I32 mark_from; |
|
831
|
|
|
|
|
|
|
I32 mark_to; |
|
832
|
|
|
|
|
|
|
I32 i; |
|
833
|
|
|
|
|
|
|
AV* a; |
|
834
|
|
|
|
|
|
|
|
|
835
|
0
|
|
|
|
|
|
oldmarksp = cx->blk_oldmarksp; |
|
836
|
0
|
|
|
|
|
|
mark_from = PL_markstack[oldmarksp-1]; |
|
837
|
0
|
|
|
|
|
|
mark_to = PL_markstack[oldmarksp]; |
|
838
|
|
|
|
|
|
|
|
|
839
|
0
|
0
|
|
|
|
|
if (!cx) return Nullav; |
|
840
|
0
|
|
|
|
|
|
a = newAV(); |
|
841
|
0
|
0
|
|
|
|
|
for(i=mark_from+1; i<=mark_to; ++i) |
|
842
|
0
|
0
|
|
|
|
|
if (skip-- <= 0) av_push(a, newSVsv(PL_stack_base[i])); |
|
843
|
|
|
|
|
|
|
|
|
844
|
0
|
|
|
|
|
|
return a; |
|
845
|
|
|
|
|
|
|
} |
|
846
|
|
|
|
|
|
|
|
|
847
|
|
|
|
|
|
|
/* |
|
848
|
|
|
|
|
|
|
* copy_rval - Retrieves a single scalar value passed to a subroutine. |
|
849
|
|
|
|
|
|
|
* |
|
850
|
|
|
|
|
|
|
* Arguments: |
|
851
|
|
|
|
|
|
|
* I32 uplevel - Stack level to inspect. |
|
852
|
|
|
|
|
|
|
* |
|
853
|
|
|
|
|
|
|
* Return: |
|
854
|
|
|
|
|
|
|
* AV* - An array containing one value, or Nullav if context not found. |
|
855
|
|
|
|
|
|
|
* |
|
856
|
|
|
|
|
|
|
* Description: |
|
857
|
|
|
|
|
|
|
* This function retrieves the last scalar value from the stack, wrapping it in an AV |
|
858
|
|
|
|
|
|
|
* for Perl-side use. It is used in OP_SASSIGN cases to retrieve the sole value. |
|
859
|
|
|
|
|
|
|
* |
|
860
|
|
|
|
|
|
|
* Internal: |
|
861
|
|
|
|
|
|
|
* Used by want_assign() for scalar assignment contexts. |
|
862
|
|
|
|
|
|
|
*/ |
|
863
|
|
|
|
|
|
|
AV* |
|
864
|
21
|
|
|
|
|
|
copy_rval(I32 uplevel) |
|
865
|
|
|
|
|
|
|
{ |
|
866
|
21
|
|
|
|
|
|
PERL_CONTEXT* cx = upcontext(aTHX_ uplevel); |
|
867
|
|
|
|
|
|
|
I32 oldmarksp; |
|
868
|
|
|
|
|
|
|
AV* a; |
|
869
|
|
|
|
|
|
|
|
|
870
|
21
|
|
|
|
|
|
oldmarksp = cx->blk_oldmarksp; |
|
871
|
21
|
50
|
|
|
|
|
if (!cx) return Nullav; |
|
872
|
21
|
|
|
|
|
|
a = newAV(); |
|
873
|
21
|
|
|
|
|
|
av_push(a, newSVsv(PL_stack_base[PL_markstack[oldmarksp+1]])); |
|
874
|
|
|
|
|
|
|
|
|
875
|
21
|
|
|
|
|
|
return a; |
|
876
|
|
|
|
|
|
|
} |
|
877
|
|
|
|
|
|
|
|
|
878
|
|
|
|
|
|
|
// NOTE: Module |
|
879
|
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
MODULE = Wanted PACKAGE = Wanted |
|
881
|
|
|
|
|
|
|
PROTOTYPES: ENABLE |
|
882
|
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
=begin comment |
|
884
|
|
|
|
|
|
|
// NOTE: wantarray_up |
|
885
|
|
|
|
|
|
|
/* |
|
886
|
|
|
|
|
|
|
* wantarray_up - Wrapper for Perl's wantarray at a given stack level. |
|
887
|
|
|
|
|
|
|
* |
|
888
|
|
|
|
|
|
|
* Arguments: |
|
889
|
|
|
|
|
|
|
* I32 uplevel - Call stack level offset to use. |
|
890
|
|
|
|
|
|
|
* |
|
891
|
|
|
|
|
|
|
* Return: |
|
892
|
|
|
|
|
|
|
* SV* - Returns &PL_sv_yes (true) for list context, &PL_sv_no (false) for scalar |
|
893
|
|
|
|
|
|
|
* context, or &PL_sv_undef for void context. |
|
894
|
|
|
|
|
|
|
* |
|
895
|
|
|
|
|
|
|
* Description: |
|
896
|
|
|
|
|
|
|
* This provides a consistent interface to Perl’s context detection at various call |
|
897
|
|
|
|
|
|
|
* depths. |
|
898
|
|
|
|
|
|
|
* |
|
899
|
|
|
|
|
|
|
* Internal: |
|
900
|
|
|
|
|
|
|
* Used by context(), want(), and _wantone(). |
|
901
|
|
|
|
|
|
|
*/ |
|
902
|
|
|
|
|
|
|
=cut |
|
903
|
|
|
|
|
|
|
SV* |
|
904
|
|
|
|
|
|
|
wantarray_up(uplevel) |
|
905
|
|
|
|
|
|
|
I32 uplevel; |
|
906
|
|
|
|
|
|
|
PREINIT: |
|
907
|
50
|
|
|
|
|
|
U8 gimme = want_gimme(uplevel); |
|
908
|
|
|
|
|
|
|
CODE: |
|
909
|
50
|
|
|
|
|
|
switch(gimme) |
|
910
|
|
|
|
|
|
|
{ |
|
911
|
10
|
|
|
|
|
|
case G_ARRAY: |
|
912
|
10
|
|
|
|
|
|
RETVAL = &PL_sv_yes; |
|
913
|
10
|
|
|
|
|
|
break; |
|
914
|
34
|
|
|
|
|
|
case G_SCALAR: |
|
915
|
34
|
|
|
|
|
|
RETVAL = &PL_sv_no; |
|
916
|
34
|
|
|
|
|
|
break; |
|
917
|
6
|
|
|
|
|
|
default: |
|
918
|
6
|
|
|
|
|
|
RETVAL = &PL_sv_undef; |
|
919
|
|
|
|
|
|
|
} |
|
920
|
|
|
|
|
|
|
OUTPUT: |
|
921
|
|
|
|
|
|
|
RETVAL |
|
922
|
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
=begin comment |
|
924
|
|
|
|
|
|
|
// NOTE: want_lvalue |
|
925
|
|
|
|
|
|
|
/* |
|
926
|
|
|
|
|
|
|
* want_lvalue - Detects if the current subroutine is being called in lvalue context. |
|
927
|
|
|
|
|
|
|
* |
|
928
|
|
|
|
|
|
|
* Arguments: |
|
929
|
|
|
|
|
|
|
* I32 uplevel - Number of levels up the call stack to check. |
|
930
|
|
|
|
|
|
|
* |
|
931
|
|
|
|
|
|
|
* Return: |
|
932
|
|
|
|
|
|
|
* int - Returns true (non-zero) if in lvalue context, false (0) otherwise. |
|
933
|
|
|
|
|
|
|
* |
|
934
|
|
|
|
|
|
|
* Description: |
|
935
|
|
|
|
|
|
|
* This checks whether the subroutine is being evaluated in a context where the result |
|
936
|
|
|
|
|
|
|
* can be assigned to, such as in `foo() = 42`. |
|
937
|
|
|
|
|
|
|
* |
|
938
|
|
|
|
|
|
|
* Usage: |
|
939
|
|
|
|
|
|
|
* Called internally by Perl subroutines via want('LVALUE'). |
|
940
|
|
|
|
|
|
|
* |
|
941
|
|
|
|
|
|
|
* Internal: |
|
942
|
|
|
|
|
|
|
* Used by wantassign(), lnoreturn(). |
|
943
|
|
|
|
|
|
|
*/ |
|
944
|
|
|
|
|
|
|
=cut |
|
945
|
|
|
|
|
|
|
U8 |
|
946
|
|
|
|
|
|
|
want_lvalue(uplevel) |
|
947
|
|
|
|
|
|
|
I32 uplevel; |
|
948
|
|
|
|
|
|
|
PREINIT: |
|
949
|
|
|
|
|
|
|
PERL_CONTEXT* cx; |
|
950
|
|
|
|
|
|
|
CODE: |
|
951
|
83
|
|
|
|
|
|
cx = upcontext(aTHX_ uplevel); |
|
952
|
83
|
50
|
|
|
|
|
if (!cx) RETVAL = 0; |
|
953
|
|
|
|
|
|
|
|
|
954
|
83
|
100
|
|
|
|
|
if (CvLVALUE(cx->blk_sub.cv)) |
|
955
|
69
|
|
|
|
|
|
RETVAL = CxLVAL(cx); |
|
956
|
|
|
|
|
|
|
else |
|
957
|
14
|
|
|
|
|
|
RETVAL = 0; |
|
958
|
|
|
|
|
|
|
OUTPUT: |
|
959
|
|
|
|
|
|
|
RETVAL |
|
960
|
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
=begin comment |
|
962
|
|
|
|
|
|
|
// NOTE: parent_op_name |
|
963
|
|
|
|
|
|
|
/* |
|
964
|
|
|
|
|
|
|
* parent_op_name - Returns the name of the parent OP at the requested level. |
|
965
|
|
|
|
|
|
|
* |
|
966
|
|
|
|
|
|
|
* Arguments: |
|
967
|
|
|
|
|
|
|
* I32 uplevel - How far up the call stack to look. |
|
968
|
|
|
|
|
|
|
* |
|
969
|
|
|
|
|
|
|
* Return: |
|
970
|
|
|
|
|
|
|
* In scalar context: The stringified parent op name (e.g., "aassign", "method_call", "(none)"). |
|
971
|
|
|
|
|
|
|
* In list context: A two-element list containing the parent op name and the return op name. |
|
972
|
|
|
|
|
|
|
* |
|
973
|
|
|
|
|
|
|
* Description: |
|
974
|
|
|
|
|
|
|
* This function resolves the parent op name by examining the OP tree. |
|
975
|
|
|
|
|
|
|
* If the op is a `leavesub`, this typically means the context is not well-defined. |
|
976
|
|
|
|
|
|
|
* |
|
977
|
|
|
|
|
|
|
* Internal: |
|
978
|
|
|
|
|
|
|
* Used by wantref(), bump_level(), and debugging tools. |
|
979
|
|
|
|
|
|
|
*/ |
|
980
|
|
|
|
|
|
|
=cut |
|
981
|
|
|
|
|
|
|
void |
|
982
|
|
|
|
|
|
|
parent_op_name(uplevel) |
|
983
|
|
|
|
|
|
|
I32 uplevel; |
|
984
|
|
|
|
|
|
|
PREINIT: |
|
985
|
|
|
|
|
|
|
OP *r; |
|
986
|
579
|
|
|
|
|
|
OP *o = parent_op(uplevel, &r); |
|
987
|
|
|
|
|
|
|
OP *first, *second; |
|
988
|
|
|
|
|
|
|
char *retval; |
|
989
|
|
|
|
|
|
|
PPCODE: |
|
990
|
579
|
100
|
|
|
|
|
if (!o || !r) |
|
|
|
50
|
|
|
|
|
|
|
991
|
|
|
|
|
|
|
{ |
|
992
|
118
|
50
|
|
|
|
|
EXTEND(SP, 2); |
|
993
|
118
|
|
|
|
|
|
PUSHs(sv_2mortal(newSVpv("(none)", 0))); |
|
994
|
118
|
|
|
|
|
|
PUSHs(sv_2mortal(newSVpv("(none)", 0))); |
|
995
|
|
|
|
|
|
|
} |
|
996
|
|
|
|
|
|
|
else |
|
997
|
|
|
|
|
|
|
{ |
|
998
|
461
|
100
|
|
|
|
|
if (o->op_type == OP_ENTERSUB && (first = cUNOPo->op_first) |
|
|
|
50
|
|
|
|
|
|
|
999
|
30
|
100
|
|
|
|
|
&& (second = OpSIBLING(first)) && OpSIBLING(second) != Nullop) |
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1000
|
7
|
|
|
|
|
|
retval = "method_call"; |
|
1001
|
|
|
|
|
|
|
else |
|
1002
|
454
|
|
|
|
|
|
retval = (char *)PL_op_name[o->op_type]; |
|
1003
|
461
|
50
|
|
|
|
|
if (GIMME == G_ARRAY) |
|
|
|
100
|
|
|
|
|
|
|
1004
|
|
|
|
|
|
|
{ |
|
1005
|
283
|
50
|
|
|
|
|
EXTEND(SP, 2); |
|
1006
|
283
|
|
|
|
|
|
PUSHs(sv_2mortal(newSVpv(retval, 0))); |
|
1007
|
283
|
|
|
|
|
|
PUSHs(sv_2mortal(newSVpv(PL_op_name[r->op_type], 0))); |
|
1008
|
|
|
|
|
|
|
} |
|
1009
|
|
|
|
|
|
|
else |
|
1010
|
|
|
|
|
|
|
{ |
|
1011
|
178
|
50
|
|
|
|
|
EXTEND(SP, 1); |
|
1012
|
178
|
|
|
|
|
|
PUSHs(sv_2mortal(newSVpv(retval, 0))); |
|
1013
|
|
|
|
|
|
|
} |
|
1014
|
|
|
|
|
|
|
} |
|
1015
|
|
|
|
|
|
|
|
|
1016
|
|
|
|
|
|
|
=begin comment |
|
1017
|
|
|
|
|
|
|
// NOTE: want_count |
|
1018
|
|
|
|
|
|
|
/* |
|
1019
|
|
|
|
|
|
|
* want_count - Determines how many return values are expected by the caller. |
|
1020
|
|
|
|
|
|
|
* |
|
1021
|
|
|
|
|
|
|
* Arguments: |
|
1022
|
|
|
|
|
|
|
* I32 uplevel - Number of levels up to look for the list evaluation context. |
|
1023
|
|
|
|
|
|
|
* |
|
1024
|
|
|
|
|
|
|
* Return: |
|
1025
|
|
|
|
|
|
|
* int - A count of expected return items. Returns -1 if unlimited, 0 for void, or a positive count. |
|
1026
|
|
|
|
|
|
|
* |
|
1027
|
|
|
|
|
|
|
* Description: |
|
1028
|
|
|
|
|
|
|
* This enables subs to detect how many return values the caller is expecting, |
|
1029
|
|
|
|
|
|
|
* like in `my ($a, $b) = sub();`. |
|
1030
|
|
|
|
|
|
|
* |
|
1031
|
|
|
|
|
|
|
* Internal: |
|
1032
|
|
|
|
|
|
|
* Used by howmany(), want('COUNT'), and _wantone(). |
|
1033
|
|
|
|
|
|
|
*/ |
|
1034
|
|
|
|
|
|
|
=cut |
|
1035
|
|
|
|
|
|
|
I32 |
|
1036
|
|
|
|
|
|
|
want_count(uplevel) |
|
1037
|
|
|
|
|
|
|
I32 uplevel; |
|
1038
|
|
|
|
|
|
|
PREINIT: |
|
1039
|
|
|
|
|
|
|
OP* returnop; |
|
1040
|
46
|
|
|
|
|
|
OP* o = parent_op(uplevel, &returnop); |
|
1041
|
46
|
|
|
|
|
|
U8 gimme = want_gimme(uplevel); |
|
1042
|
|
|
|
|
|
|
CODE: |
|
1043
|
46
|
100
|
|
|
|
|
if (!o) |
|
1044
|
|
|
|
|
|
|
{ |
|
1045
|
4
|
50
|
|
|
|
|
RETVAL = (gimme == G_SCALAR ? 1 : gimme == G_ARRAY ? -1 : 0); |
|
|
|
50
|
|
|
|
|
|
|
1046
|
|
|
|
|
|
|
} |
|
1047
|
42
|
100
|
|
|
|
|
else if (o->op_type == OP_AASSIGN) |
|
1048
|
|
|
|
|
|
|
{ |
|
1049
|
35
|
|
|
|
|
|
I32 lhs = count_list(cBINOPo->op_last, Nullop ); |
|
1050
|
35
|
|
|
|
|
|
I32 rhs = countstack(uplevel); |
|
1051
|
35
|
100
|
|
|
|
|
if (lhs == 0) RETVAL = -1; |
|
1052
|
17
|
100
|
|
|
|
|
else if (rhs >= lhs-1) RETVAL = 0; |
|
1053
|
13
|
|
|
|
|
|
else RETVAL = lhs - rhs - 1; |
|
1054
|
|
|
|
|
|
|
} |
|
1055
|
7
|
|
|
|
|
|
else switch(gimme) |
|
1056
|
|
|
|
|
|
|
{ |
|
1057
|
1
|
|
|
|
|
|
case G_ARRAY: |
|
1058
|
1
|
|
|
|
|
|
RETVAL = -1; |
|
1059
|
1
|
|
|
|
|
|
break; |
|
1060
|
6
|
|
|
|
|
|
case G_SCALAR: |
|
1061
|
6
|
|
|
|
|
|
RETVAL = 1; |
|
1062
|
6
|
|
|
|
|
|
break; |
|
1063
|
0
|
|
|
|
|
|
default: |
|
1064
|
0
|
|
|
|
|
|
RETVAL = 0; |
|
1065
|
|
|
|
|
|
|
} |
|
1066
|
|
|
|
|
|
|
OUTPUT: |
|
1067
|
|
|
|
|
|
|
RETVAL |
|
1068
|
|
|
|
|
|
|
|
|
1069
|
|
|
|
|
|
|
=begin comment |
|
1070
|
|
|
|
|
|
|
// NOTE: want_boolean |
|
1071
|
|
|
|
|
|
|
/* |
|
1072
|
|
|
|
|
|
|
* want_boolean - Determines whether the current expression is evaluated in boolean context. |
|
1073
|
|
|
|
|
|
|
* |
|
1074
|
|
|
|
|
|
|
* Arguments: |
|
1075
|
|
|
|
|
|
|
* I32 uplevel - Stack level to examine. |
|
1076
|
|
|
|
|
|
|
* |
|
1077
|
|
|
|
|
|
|
* Return: |
|
1078
|
|
|
|
|
|
|
* int - Boolean true/false indicating if this is boolean context. |
|
1079
|
|
|
|
|
|
|
* |
|
1080
|
|
|
|
|
|
|
* Description: |
|
1081
|
|
|
|
|
|
|
* This inspects the op tree to determine if the result of the function is |
|
1082
|
|
|
|
|
|
|
* being evaluated as a truth value (e.g., `if(foo())` or `foo() && 1`). |
|
1083
|
|
|
|
|
|
|
* |
|
1084
|
|
|
|
|
|
|
* Internal: |
|
1085
|
|
|
|
|
|
|
* Used by want('BOOL'). |
|
1086
|
|
|
|
|
|
|
*/ |
|
1087
|
|
|
|
|
|
|
=cut |
|
1088
|
|
|
|
|
|
|
bool |
|
1089
|
|
|
|
|
|
|
want_boolean(uplevel) |
|
1090
|
|
|
|
|
|
|
I32 uplevel; |
|
1091
|
|
|
|
|
|
|
PREINIT: |
|
1092
|
73
|
|
|
|
|
|
oplist* l = ancestor_ops(uplevel, 0); |
|
1093
|
|
|
|
|
|
|
U16 i; |
|
1094
|
73
|
|
|
|
|
|
bool truebool = FALSE, pseudobool = FALSE; |
|
1095
|
|
|
|
|
|
|
CODE: |
|
1096
|
73
|
100
|
|
|
|
|
if (!l) |
|
1097
|
|
|
|
|
|
|
{ |
|
1098
|
5
|
|
|
|
|
|
RETVAL = FALSE; |
|
1099
|
|
|
|
|
|
|
} |
|
1100
|
|
|
|
|
|
|
else |
|
1101
|
|
|
|
|
|
|
{ |
|
1102
|
267
|
100
|
|
|
|
|
for( i=0; i < l->length; ++i ) |
|
1103
|
|
|
|
|
|
|
{ |
|
1104
|
199
|
|
|
|
|
|
OP* o = l->ops[i].numop_op; |
|
1105
|
199
|
|
|
|
|
|
U16 n = l->ops[i].numop_num; |
|
1106
|
199
|
100
|
|
|
|
|
bool v = (OP_GIMME(o, -1) == G_VOID); |
|
|
|
100
|
|
|
|
|
|
|
1107
|
199
|
|
|
|
|
|
switch(o->op_type) |
|
1108
|
|
|
|
|
|
|
{ |
|
1109
|
13
|
|
|
|
|
|
case OP_NOT: |
|
1110
|
|
|
|
|
|
|
case OP_XOR: |
|
1111
|
13
|
|
|
|
|
|
truebool = TRUE; |
|
1112
|
13
|
|
|
|
|
|
break; |
|
1113
|
34
|
|
|
|
|
|
case OP_AND: |
|
1114
|
34
|
100
|
|
|
|
|
if (truebool || v) |
|
|
|
100
|
|
|
|
|
|
|
1115
|
30
|
|
|
|
|
|
truebool = TRUE; |
|
1116
|
|
|
|
|
|
|
else |
|
1117
|
4
|
50
|
|
|
|
|
pseudobool = (pseudobool || n == 0); |
|
|
|
100
|
|
|
|
|
|
|
1118
|
34
|
|
|
|
|
|
break; |
|
1119
|
15
|
|
|
|
|
|
case OP_OR: |
|
1120
|
15
|
100
|
|
|
|
|
if (truebool || v) |
|
|
|
100
|
|
|
|
|
|
|
1121
|
12
|
|
|
|
|
|
truebool = TRUE; |
|
1122
|
|
|
|
|
|
|
else |
|
1123
|
3
|
|
|
|
|
|
truebool = FALSE; |
|
1124
|
15
|
|
|
|
|
|
break; |
|
1125
|
6
|
|
|
|
|
|
case OP_COND_EXPR: |
|
1126
|
6
|
100
|
|
|
|
|
truebool = (truebool || n == 0); |
|
|
|
100
|
|
|
|
|
|
|
1127
|
6
|
|
|
|
|
|
break; |
|
1128
|
64
|
|
|
|
|
|
case OP_NULL: |
|
1129
|
64
|
|
|
|
|
|
break; |
|
1130
|
67
|
|
|
|
|
|
default: |
|
1131
|
67
|
|
|
|
|
|
truebool = FALSE; |
|
1132
|
67
|
|
|
|
|
|
pseudobool = FALSE; |
|
1133
|
|
|
|
|
|
|
} |
|
1134
|
|
|
|
|
|
|
} |
|
1135
|
68
|
|
|
|
|
|
free(l); |
|
1136
|
68
|
100
|
|
|
|
|
RETVAL = truebool || pseudobool; |
|
|
|
100
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
} |
|
1138
|
|
|
|
|
|
|
OUTPUT: |
|
1139
|
|
|
|
|
|
|
RETVAL |
|
1140
|
|
|
|
|
|
|
|
|
1141
|
|
|
|
|
|
|
=begin comment |
|
1142
|
|
|
|
|
|
|
// NOTE: want_assign |
|
1143
|
|
|
|
|
|
|
/* |
|
1144
|
|
|
|
|
|
|
* want_assign - Retrieves the right-hand-side values in an assignment context. |
|
1145
|
|
|
|
|
|
|
* |
|
1146
|
|
|
|
|
|
|
* Arguments: |
|
1147
|
|
|
|
|
|
|
* I32 uplevel - Number of levels up the call stack to inspect. |
|
1148
|
|
|
|
|
|
|
* |
|
1149
|
|
|
|
|
|
|
* Return: |
|
1150
|
|
|
|
|
|
|
* SV* - A reference to an array containing the right-hand-side (RHS) values, |
|
1151
|
|
|
|
|
|
|
* or &PL_sv_undef if not in assignment context. |
|
1152
|
|
|
|
|
|
|
* |
|
1153
|
|
|
|
|
|
|
* Description: |
|
1154
|
|
|
|
|
|
|
* This XS function inspects the current call context to determine if a subroutine is |
|
1155
|
|
|
|
|
|
|
* being assigned to. If so, it captures and returns the values being assigned. |
|
1156
|
|
|
|
|
|
|
* |
|
1157
|
|
|
|
|
|
|
* Internal: |
|
1158
|
|
|
|
|
|
|
* Used by wantassign() to expose assignment RHS values to Perl. |
|
1159
|
|
|
|
|
|
|
*/ |
|
1160
|
|
|
|
|
|
|
=cut |
|
1161
|
|
|
|
|
|
|
SV* |
|
1162
|
|
|
|
|
|
|
want_assign(uplevel) |
|
1163
|
|
|
|
|
|
|
U32 uplevel; |
|
1164
|
|
|
|
|
|
|
PREINIT: |
|
1165
|
|
|
|
|
|
|
AV* r; |
|
1166
|
|
|
|
|
|
|
OP* returnop; |
|
1167
|
23
|
|
|
|
|
|
oplist* os = ancestor_ops(uplevel, &returnop); |
|
1168
|
23
|
50
|
|
|
|
|
numop* lno = os ? lastnumop(os) : (numop*)0; |
|
1169
|
|
|
|
|
|
|
OPCODE type; |
|
1170
|
|
|
|
|
|
|
PPCODE: |
|
1171
|
23
|
50
|
|
|
|
|
if (!lno) |
|
1172
|
|
|
|
|
|
|
{ |
|
1173
|
0
|
|
|
|
|
|
r = Nullav; |
|
1174
|
|
|
|
|
|
|
} |
|
1175
|
|
|
|
|
|
|
else |
|
1176
|
|
|
|
|
|
|
{ |
|
1177
|
23
|
|
|
|
|
|
type = lno->numop_op->op_type; |
|
1178
|
23
|
50
|
|
|
|
|
if (lno && (type == OP_AASSIGN || type == OP_SASSIGN) && lno->numop_num == 1) |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
1179
|
|
|
|
|
|
|
{ |
|
1180
|
21
|
50
|
|
|
|
|
if (type == OP_AASSIGN) |
|
1181
|
|
|
|
|
|
|
{ |
|
1182
|
0
|
|
|
|
|
|
I32 lhs_count = count_list(cBINOPx(lno->numop_op)->op_last, returnop); |
|
1183
|
0
|
0
|
|
|
|
|
if (lhs_count == 0) r = newAV(); |
|
1184
|
|
|
|
|
|
|
else |
|
1185
|
|
|
|
|
|
|
{ |
|
1186
|
0
|
|
|
|
|
|
r = copy_rvals(uplevel, lhs_count-1); |
|
1187
|
|
|
|
|
|
|
} |
|
1188
|
|
|
|
|
|
|
} |
|
1189
|
21
|
|
|
|
|
|
else r = copy_rval(uplevel); |
|
1190
|
|
|
|
|
|
|
} |
|
1191
|
|
|
|
|
|
|
else |
|
1192
|
|
|
|
|
|
|
{ |
|
1193
|
2
|
|
|
|
|
|
r = Nullav; |
|
1194
|
|
|
|
|
|
|
} |
|
1195
|
|
|
|
|
|
|
} |
|
1196
|
23
|
50
|
|
|
|
|
if (os) free(os); |
|
1197
|
|
|
|
|
|
|
|
|
1198
|
23
|
50
|
|
|
|
|
EXTEND(SP, 1); |
|
1199
|
23
|
100
|
|
|
|
|
PUSHs(r ? sv_2mortal(newRV_noinc((SV*) r)) : &PL_sv_undef); |
|
1200
|
|
|
|
|
|
|
|
|
1201
|
|
|
|
|
|
|
=begin comment |
|
1202
|
|
|
|
|
|
|
// NOTE: double_return |
|
1203
|
|
|
|
|
|
|
/* |
|
1204
|
|
|
|
|
|
|
* double_return - Restores nested return context. |
|
1205
|
|
|
|
|
|
|
* |
|
1206
|
|
|
|
|
|
|
* Description: |
|
1207
|
|
|
|
|
|
|
* This function simulates a return from a subroutine by manipulating the context stack. |
|
1208
|
|
|
|
|
|
|
* It is tightly coupled to Perl's internal context stack and was originally implemented |
|
1209
|
|
|
|
|
|
|
* in version 1 of Want. It has been retained as-is for compatibility. |
|
1210
|
|
|
|
|
|
|
* |
|
1211
|
|
|
|
|
|
|
* Notes: |
|
1212
|
|
|
|
|
|
|
* Wrapped in PERL_VERSION_GE(5, 8, 8) and ENABLE_DOUBLE_RETURN_HACKS for safety. |
|
1213
|
|
|
|
|
|
|
* ⚠️ Do not modify unless you deeply understand the implications, as changes can |
|
1214
|
|
|
|
|
|
|
* lead to crashes or undefined behaviour. |
|
1215
|
|
|
|
|
|
|
* |
|
1216
|
|
|
|
|
|
|
* Internal: |
|
1217
|
|
|
|
|
|
|
* Used by rreturn() and lnoreturn() to implement early returns in Perl code. |
|
1218
|
|
|
|
|
|
|
*/ |
|
1219
|
|
|
|
|
|
|
=cut |
|
1220
|
|
|
|
|
|
|
void |
|
1221
|
|
|
|
|
|
|
double_return(...) |
|
1222
|
|
|
|
|
|
|
PREINIT: |
|
1223
|
|
|
|
|
|
|
PERL_CONTEXT *ourcx, *cx; |
|
1224
|
|
|
|
|
|
|
PPCODE: |
|
1225
|
|
|
|
|
|
|
# if PERL_VERSION_GE(5, 8, 8) && ENABLE_DOUBLE_RETURN_HACKS |
|
1226
|
23
|
|
|
|
|
|
ourcx = upcontext(aTHX_ 0); |
|
1227
|
23
|
|
|
|
|
|
cx = upcontext(aTHX_ 1); |
|
1228
|
23
|
100
|
|
|
|
|
if (!cx) |
|
1229
|
2
|
|
|
|
|
|
Perl_croak(aTHX_ "Can't return outside a subroutine"); |
|
1230
|
|
|
|
|
|
|
#ifdef POPBLOCK |
|
1231
|
|
|
|
|
|
|
ourcx->cx_type = CXt_NULL; |
|
1232
|
|
|
|
|
|
|
CvDEPTH(ourcx->blk_sub.cv)--; |
|
1233
|
|
|
|
|
|
|
# if HAS_RETSTACK |
|
1234
|
|
|
|
|
|
|
if (PL_retstack_ix > 0) |
|
1235
|
|
|
|
|
|
|
--PL_retstack_ix; |
|
1236
|
|
|
|
|
|
|
# endif |
|
1237
|
|
|
|
|
|
|
#else |
|
1238
|
|
|
|
|
|
|
/* In 5.23.8 or later, PL_curpad is saved in the context stack and |
|
1239
|
|
|
|
|
|
|
* restored by cx_popsub(), rather than being saved on the savestack |
|
1240
|
|
|
|
|
|
|
* and restored by LEAVE; so just CXt_NULLing the parent sub |
|
1241
|
|
|
|
|
|
|
* skips the PL_curpad restore and so everything done during the |
|
1242
|
|
|
|
|
|
|
* second part of the return will have the wrong PL_curpad. |
|
1243
|
|
|
|
|
|
|
* So instead, fix up the first return so that it thinks the |
|
1244
|
|
|
|
|
|
|
* op to continue at is iteself, forcing it to do a double return. |
|
1245
|
|
|
|
|
|
|
*/ |
|
1246
|
|
|
|
|
|
|
assert(PL_op->op_next->op_type == OP_RETURN); |
|
1247
|
|
|
|
|
|
|
/* force the op following the 'return' to be 'return' again */ |
|
1248
|
21
|
|
|
|
|
|
ourcx->blk_sub.retop = PL_op->op_next; |
|
1249
|
|
|
|
|
|
|
assert(PL_markstack + ourcx->blk_oldmarksp + 1 == PL_markstack_ptr); |
|
1250
|
21
|
|
|
|
|
|
ourcx->blk_oldmarksp++; |
|
1251
|
21
|
|
|
|
|
|
ourcx->blk_gimme = cx->blk_gimme; |
|
1252
|
|
|
|
|
|
|
#endif |
|
1253
|
|
|
|
|
|
|
|
|
1254
|
21
|
|
|
|
|
|
return; |
|
1255
|
|
|
|
|
|
|
# else |
|
1256
|
|
|
|
|
|
|
Perl_croak(aTHX_ "double_return not supported on Perl %d.%d.%d (requires >= 5.8.8)", |
|
1257
|
|
|
|
|
|
|
PERL_REVISION, PERL_VERSION, PERL_SUBVERSION); |
|
1258
|
|
|
|
|
|
|
# endif /* PERL_VERSION_GE && ENABLE_DOUBLE_RETURN_HACKS */ |
|
1259
|
|
|
|
|
|
|
|
|
1260
|
|
|
|
|
|
|
=begin comment |
|
1261
|
|
|
|
|
|
|
// NOTE: disarm_temp |
|
1262
|
|
|
|
|
|
|
/* |
|
1263
|
|
|
|
|
|
|
* disarm_temp - Prevents premature destruction of temporary SVs. |
|
1264
|
|
|
|
|
|
|
* |
|
1265
|
|
|
|
|
|
|
* Arguments: |
|
1266
|
|
|
|
|
|
|
* SV* sv - A scalar value which would normally be discarded or freed. |
|
1267
|
|
|
|
|
|
|
* |
|
1268
|
|
|
|
|
|
|
* Return: |
|
1269
|
|
|
|
|
|
|
* SV* - A new scalar that holds the value of the temporary, protected from auto-cleanup. |
|
1270
|
|
|
|
|
|
|
* |
|
1271
|
|
|
|
|
|
|
* Description: |
|
1272
|
|
|
|
|
|
|
* This is used to hold a temporary value in a persistent form for use in lvalue context. |
|
1273
|
|
|
|
|
|
|
* It ensures the SV is detached from temporary cleanup scopes. |
|
1274
|
|
|
|
|
|
|
* |
|
1275
|
|
|
|
|
|
|
* Usage: |
|
1276
|
|
|
|
|
|
|
* return disarm_temp(newSViv(0)); // safe to return from XS |
|
1277
|
|
|
|
|
|
|
* |
|
1278
|
|
|
|
|
|
|
* Internal: |
|
1279
|
|
|
|
|
|
|
* Used by lnoreturn() to safely return placeholder values. |
|
1280
|
|
|
|
|
|
|
*/ |
|
1281
|
|
|
|
|
|
|
=cut |
|
1282
|
|
|
|
|
|
|
SV * |
|
1283
|
|
|
|
|
|
|
disarm_temp(sv) |
|
1284
|
|
|
|
|
|
|
SV *sv; |
|
1285
|
|
|
|
|
|
|
CODE: |
|
1286
|
9
|
|
|
|
|
|
RETVAL = sv_2mortal(SvREFCNT_inc(SvREFCNT_inc(sv))); |
|
1287
|
|
|
|
|
|
|
OUTPUT: |
|
1288
|
|
|
|
|
|
|
RETVAL |
|
1289
|
|
|
|
|
|
|
|
|
1290
|
|
|
|
|
|
|
INCLUDE: FirstMultideref.xsh |