64
64
65
65
public class PCode extends PythonBuiltinObject {
66
66
private final RootNode rootNode ;
67
+ private final PythonCore core ;
68
+
67
69
// number of arguments (not including keyword only arguments, * or ** args)
68
- private final int argcount ;
70
+ private int argcount = - 1 ;
69
71
// number of keyword only arguments (not including ** arg)
70
- private final int kwonlyargcount ;
72
+ private int kwonlyargcount = - 1 ;
71
73
// number of local variables
72
- private final int nlocals ;
74
+ private int nlocals = - 1 ;
73
75
// is the required stack size (including local variables)
74
- private final int stacksize ;
76
+ private int stacksize = - 1 ;
75
77
// is an integer encoding a number of flags for the interpreter.
76
- //
77
78
// The following flag bits are defined for co_flags: bit 0x04 is set if the function uses the
78
79
// *arguments syntax to accept an arbitrary number of positional arguments; bit 0x08 is set if
79
80
// the function uses the **keywords syntax to accept arbitrary keyword arguments; bit 0x20 is
80
81
// set if the function is a generator.
81
- private final int flags ;
82
+ private int flags = - 1 ;
82
83
// is a string representing the sequence of bytecode instructions
83
- private final String codestring ;
84
+ private String codestring ;
84
85
// tuple of constants used in the bytecode
85
- private final Object constants ;
86
+ private Object constants ;
86
87
// tuple containing the literals used by the bytecode
87
- private final Object names ;
88
+ private Object names ;
88
89
// is a tuple containing the names of the local variables (starting with the argument names)
89
- private final Object [] varnames ;
90
+ private Object [] varnames ;
90
91
// name of file in which this code object was created
91
- private final String filename ;
92
+ private String filename ;
92
93
// name with which this code object was defined
93
- private final String name ;
94
+ private String name ;
94
95
// number of first line in Python source code
95
- private final int firstlineno ;
96
+ private int firstlineno = - 1 ;
96
97
// is a string encoding the mapping from bytecode offsets to line numbers
97
- private final Object lnotab ;
98
+ private Object lnotab ;
98
99
// tuple of names of free variables (referenced via a function’s closure)
99
- private final Object [] freevars ;
100
+ private Object [] freevars ;
100
101
// tuple of names of cell variables (referenced by containing scopes)
101
- private final Object [] cellvars ;
102
+ private Object [] cellvars ;
102
103
103
104
@ TruffleBoundary
104
105
public PCode (PythonClass cls , RootNode rootNode , PythonCore core ) {
105
106
super (cls );
106
107
this .rootNode = rootNode ;
107
- // file stats
108
- this .filename = getFileName (this .rootNode );
109
- this .name = getName (this .rootNode );
110
- this .firstlineno = getFirstLineno (this .rootNode );
111
- // arg stats
112
- ArgStats argStats = getArgStats (this .rootNode , core );
113
- this .argcount = argStats .argCnt ;
114
- this .kwonlyargcount = argStats .kwOnlyArgCnt ;
115
- this .freevars = argStats .freeVars ;
116
- this .cellvars = argStats .cellVars ;
117
- this .varnames = argStats .varNames ;
118
- this .nlocals = argStats .nLocals ;
119
- this .flags = argStats .flags ;
120
-
121
- this .stacksize = getStackSize (rootNode );
122
- this .codestring = null ;
123
- this .constants = null ;
124
- this .names = null ;
125
- this .lnotab = null ;
108
+ this .core = core ;
126
109
}
127
110
128
111
public PCode (PythonClass cls , int argcount , int kwonlyargcount ,
@@ -133,6 +116,8 @@ public PCode(PythonClass cls, int argcount, int kwonlyargcount,
133
116
Object lnotab ) {
134
117
super (cls );
135
118
this .rootNode = null ;
119
+ this .core = null ;
120
+
136
121
this .argcount = argcount ;
137
122
this .kwonlyargcount = kwonlyargcount ;
138
123
this .nlocals = nlocals ;
@@ -174,7 +159,7 @@ private static String[] getCellVars(RootNode rootNode) {
174
159
}
175
160
}
176
161
177
- private static String getFileName (RootNode rootNode ) {
162
+ private static String extractFileName (RootNode rootNode ) {
178
163
SourceSection src = rootNode .getSourceSection ();
179
164
if (src != null ) {
180
165
return src .getSource ().getName ();
@@ -185,12 +170,12 @@ private static String getFileName(RootNode rootNode) {
185
170
}
186
171
}
187
172
188
- private static int getFirstLineno (RootNode rootNode ) {
173
+ private static int extractFirstLineno (RootNode rootNode ) {
189
174
SourceSection sourceSection = rootNode .getSourceSection ();
190
175
return (sourceSection != null ) ? sourceSection .getStartLine () : 1 ;
191
176
}
192
177
193
- private static String getName (RootNode rootNode ) {
178
+ private static String extractName (RootNode rootNode ) {
194
179
String name ;
195
180
if (rootNode instanceof ModuleRootNode ) {
196
181
name = "<module>" ;
@@ -224,31 +209,15 @@ private static Set<String> getArgumentNames(List<ReadIndexedArgumentNode> readIn
224
209
return argNames ;
225
210
}
226
211
227
- private final static class ArgStats {
228
- final int argCnt ;
229
- final int kwOnlyArgCnt ;
230
- final Object [] varNames ;
231
- final Object [] freeVars ;
232
- final Object [] cellVars ;
233
- final int flags ;
234
- final int nLocals ;
235
-
236
- private ArgStats (int argCnt , int kwOnlyArgCnt , Object [] varNames , Object [] freeVars , Object [] cellVars , int flags ) {
237
- this .argCnt = argCnt ;
238
- this .kwOnlyArgCnt = kwOnlyArgCnt ;
239
- this .varNames = varNames ;
240
- this .freeVars = freeVars ;
241
- this .cellVars = cellVars ;
242
- this .nLocals = varNames .length ;
243
- this .flags = flags ;
244
- }
212
+ private static int extractStackSize (RootNode rootNode ) {
213
+ return rootNode .getFrameDescriptor ().getSize ();
245
214
}
246
215
247
- private static ArgStats getArgStats ( RootNode rootNode , PythonCore core ) {
248
- String [] freeVars = getFreeVars (rootNode );
249
- String [] cellVars = getCellVars (rootNode );
250
- Set <String > freeVarsSet = asSet (freeVars );
251
- Set <String > cellVarsSet = asSet (cellVars );
216
+ private void extractArgStats ( ) {
217
+ String [] freevars = getFreeVars (rootNode );
218
+ String [] cellvars = getCellVars (rootNode );
219
+ Set <String > freeVarsSet = asSet (freevars );
220
+ Set <String > cellVarsSet = asSet (cellvars );
252
221
253
222
List <ReadKeywordNode > readKeywordNodes = NodeUtil .findAllNodeInstances (rootNode , ReadKeywordNode .class );
254
223
List <ReadIndexedArgumentNode > readIndexedArgumentNodes = NodeUtil .findAllNodeInstances (rootNode , ReadIndexedArgumentNode .class );
@@ -260,26 +229,26 @@ private static ArgStats getArgStats(RootNode rootNode, PythonCore core) {
260
229
allArgNames .addAll (kwNames );
261
230
allArgNames .addAll (argNames );
262
231
263
- int argC = readIndexedArgumentNodes .size ();
264
- int kwOnlyArgC = 0 ;
232
+ int argcount = readIndexedArgumentNodes .size ();
233
+ int kwonlyargcount = 0 ;
265
234
int flags = 0 ;
266
235
267
236
for (ReadKeywordNode kwNode : readKeywordNodes ) {
268
237
if (!kwNode .canBePositional ()) {
269
- kwOnlyArgC ++;
238
+ kwonlyargcount ++;
270
239
}
271
240
}
272
241
273
- Set <String > varNames = new HashSet <>();
242
+ Set <String > varnames = new HashSet <>();
274
243
for (Object identifier : rootNode .getFrameDescriptor ().getIdentifiers ()) {
275
244
if (identifier instanceof String ) {
276
245
String varName = (String ) identifier ;
277
246
278
247
if (core .getParser ().isIdentifier (core , varName )) {
279
248
if (allArgNames .contains (varName )) {
280
- varNames .add (varName );
249
+ varnames .add (varName );
281
250
} else if (!freeVarsSet .contains (varName ) && !cellVarsSet .contains (varName )) {
282
- varNames .add (varName );
251
+ varnames .add (varName );
283
252
}
284
253
}
285
254
}
@@ -299,57 +268,96 @@ private static ArgStats getArgStats(RootNode rootNode, PythonCore core) {
299
268
flags |= (1 << 5 );
300
269
}
301
270
302
- return new ArgStats (argC , kwOnlyArgC , varNames .toArray (), freeVars , cellVars , flags );
303
- }
304
-
305
- private static int getStackSize (RootNode rootNode ) {
306
- return rootNode .getFrameDescriptor ().getSize ();
271
+ this .argcount = argcount ;
272
+ this .kwonlyargcount = kwonlyargcount ;
273
+ this .freevars = freevars ;
274
+ this .cellvars = cellvars ;
275
+ this .varnames = varnames .toArray ();
276
+ this .nlocals = varnames .size ();
277
+ this .flags = flags ;
307
278
}
308
279
309
280
public RootNode getRootNode () {
310
281
return rootNode ;
311
282
}
312
283
313
284
public Object [] getFreeVars () {
285
+ if (freevars == null && rootNode != null ) {
286
+ extractArgStats ();
287
+ }
314
288
return freevars ;
315
289
}
316
290
317
291
public Object [] getCellVars () {
292
+ if (freevars == null && rootNode != null ) {
293
+ extractArgStats ();
294
+ }
318
295
return cellvars ;
319
296
}
320
297
321
298
public String getFilename () {
299
+ if (filename == null && rootNode != null ) {
300
+ filename = extractFileName (rootNode );
301
+ }
322
302
return filename ;
323
303
}
324
304
325
305
public int getFirstLineNo () {
306
+ if (firstlineno == -1 && rootNode != null ) {
307
+ firstlineno = extractFirstLineno (rootNode );
308
+ }
326
309
return firstlineno ;
327
310
}
328
311
329
312
public String getName () {
313
+ if (name == null && rootNode != null ) {
314
+ name = extractName (rootNode );
315
+ }
330
316
return name ;
331
317
}
332
318
333
319
public int getArgcount () {
320
+ if (argcount == -1 && rootNode != null ) {
321
+ extractArgStats ();
322
+ }
334
323
return argcount ;
335
324
}
336
325
337
326
public int getKwonlyargcount () {
327
+ if (kwonlyargcount == -1 && rootNode != null ) {
328
+ extractArgStats ();
329
+ }
338
330
return kwonlyargcount ;
339
331
}
340
332
341
333
public int getNlocals () {
334
+ if (nlocals == -1 && rootNode != null ) {
335
+ extractArgStats ();
336
+ }
342
337
return nlocals ;
343
338
}
344
339
345
340
public int getStacksize () {
341
+ if (stacksize == -1 && rootNode != null ) {
342
+ stacksize = extractStackSize (rootNode );
343
+ }
346
344
return stacksize ;
347
345
}
348
346
349
347
public long getFlags () {
348
+ if (flags == -1 && rootNode != null ) {
349
+ extractArgStats ();
350
+ }
350
351
return flags ;
351
352
}
352
353
354
+ public Object [] getVarnames () {
355
+ if (varnames == null && rootNode != null ) {
356
+ extractArgStats ();
357
+ }
358
+ return varnames ;
359
+ }
360
+
353
361
public String getCodestring () {
354
362
return codestring ;
355
363
}
@@ -362,10 +370,6 @@ public Object getNames() {
362
370
return names ;
363
371
}
364
372
365
- public Object [] getVarnames () {
366
- return varnames ;
367
- }
368
-
369
373
public Object getLnotab () {
370
374
return lnotab ;
371
375
}
0 commit comments