45
45
import java .util .List ;
46
46
import java .util .Set ;
47
47
48
+ import com .oracle .graal .python .builtins .objects .function .Arity ;
48
49
import com .oracle .graal .python .builtins .objects .object .PythonBuiltinObject ;
49
50
import com .oracle .graal .python .builtins .objects .type .PythonClass ;
50
51
import com .oracle .graal .python .nodes .ModuleRootNode ;
57
58
import com .oracle .graal .python .nodes .generator .GeneratorFunctionRootNode ;
58
59
import com .oracle .graal .python .runtime .PythonCore ;
59
60
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
61
+ import com .oracle .truffle .api .RootCallTarget ;
62
+ import com .oracle .truffle .api .Truffle ;
63
+ import com .oracle .truffle .api .frame .FrameDescriptor ;
60
64
import com .oracle .truffle .api .nodes .Node ;
61
65
import com .oracle .truffle .api .nodes .NodeUtil ;
62
66
import com .oracle .truffle .api .nodes .RootNode ;
63
67
import com .oracle .truffle .api .source .SourceSection ;
64
68
65
69
public class PCode extends PythonBuiltinObject {
70
+ private final long FLAG_POS_GENERATOR = 5 ;
71
+ private final long FLAG_POS_VAR_ARGS = 2 ;
72
+ private final long FLAG_POS_VAR_KW_ARGS = 3 ;
73
+
66
74
private final RootNode rootNode ;
67
75
private final PythonCore core ;
68
76
@@ -101,6 +109,11 @@ public class PCode extends PythonBuiltinObject {
101
109
// tuple of names of cell variables (referenced by containing scopes)
102
110
private Object [] cellvars ;
103
111
112
+ // internal cache for keyword names
113
+ private Arity .KeywordName [] keywordNames ;
114
+ // internal cache for the FrameDescriptor
115
+ private FrameDescriptor frameDescriptor ;
116
+
104
117
public PCode (PythonClass cls , RootNode rootNode , PythonCore core ) {
105
118
super (cls );
106
119
this .rootNode = rootNode ;
@@ -223,17 +236,17 @@ private void extractArgStats() {
223
236
this .flags = 0 ;
224
237
RootNode funcRootNode = rootNode ;
225
238
if (funcRootNode instanceof GeneratorFunctionRootNode ) {
226
- flags |= (1 << 5 );
239
+ flags |= (1 << FLAG_POS_GENERATOR );
227
240
funcRootNode = ((GeneratorFunctionRootNode ) funcRootNode ).getFunctionRootNode ();
228
241
}
229
242
230
243
// 0x04 - *arguments
231
244
if (NodeUtil .findAllNodeInstances (funcRootNode , ReadVarArgsNode .class ).size () == 1 ) {
232
- flags |= (1 << 2 );
245
+ flags |= (1 << FLAG_POS_VAR_ARGS );
233
246
}
234
247
// 0x08 - **keywords
235
248
if (NodeUtil .findAllNodeInstances (funcRootNode , ReadVarKeywordsNode .class ).size () == 1 ) {
236
- flags |= (1 << 3 );
249
+ flags |= (1 << FLAG_POS_VAR_KW_ARGS );
237
250
}
238
251
239
252
this .freevars = extractFreeVars (rootNode );
@@ -242,6 +255,7 @@ private void extractArgStats() {
242
255
Set <String > cellVarsSet = asSet ((String []) cellvars );
243
256
244
257
List <ReadKeywordNode > readKeywordNodes = NodeUtil .findAllNodeInstances (funcRootNode , ReadKeywordNode .class );
258
+ keywordNames = new Arity .KeywordName [readKeywordNodes .size ()];
245
259
List <ReadIndexedArgumentNode > readIndexedArgumentNodes = NodeUtil .findAllNodeInstances (funcRootNode , ReadIndexedArgumentNode .class );
246
260
247
261
Set <String > kwNames = getKeywordArgumentNames (readKeywordNodes );
@@ -254,7 +268,9 @@ private void extractArgStats() {
254
268
this .argcount = readIndexedArgumentNodes .size ();
255
269
this .kwonlyargcount = 0 ;
256
270
257
- for (ReadKeywordNode kwNode : readKeywordNodes ) {
271
+ for (int i = 0 ; i < readKeywordNodes .size (); i ++) {
272
+ ReadKeywordNode kwNode = readKeywordNodes .get (i );
273
+ keywordNames [i ++] = new Arity .KeywordName (kwNode .getName (), kwNode .isRequired ());
258
274
if (!kwNode .canBePositional ()) {
259
275
kwonlyargcount ++;
260
276
}
@@ -375,4 +391,58 @@ public Object getNames() {
375
391
public Object getLnotab () {
376
392
return lnotab ;
377
393
}
394
+
395
+ public Arity .KeywordName [] getKeywordNames () {
396
+ if (keywordNames == null && rootNode != null ) {
397
+ extractArgStats ();
398
+ }
399
+ return keywordNames ;
400
+ }
401
+
402
+ public boolean isGenerator () {
403
+ long flags = getFlags ();
404
+ return (flags & (1 << FLAG_POS_GENERATOR )) > 0 ;
405
+ }
406
+
407
+ public boolean takesVarArgs () {
408
+ long flags = getFlags ();
409
+ return (flags & (1 << FLAG_POS_VAR_ARGS )) > 0 ;
410
+ }
411
+
412
+ public boolean takesVarKeywordArgs () {
413
+ long flags = getFlags ();
414
+ return (flags & (1 << FLAG_POS_VAR_KW_ARGS )) > 0 ;
415
+ }
416
+
417
+ public Arity getArity () {
418
+ return new Arity (this .getName (), this .getArgcount (), this .getArgcount () + this .getKwonlyargcount (), this .takesVarKeywordArgs (), this .takesVarArgs (), this .getKeywordNames ());
419
+ }
420
+
421
+ @ TruffleBoundary
422
+ private FrameDescriptor createFrameDescriptor () {
423
+ FrameDescriptor fd = new FrameDescriptor ();
424
+ for (Object identifier : varnames ) {
425
+ fd .addFrameSlot (identifier );
426
+ }
427
+ return fd ;
428
+ }
429
+
430
+ public FrameDescriptor getFrameDescriptor () {
431
+ if (frameDescriptor == null ) {
432
+ if (rootNode != null ) {
433
+ frameDescriptor = rootNode .getFrameDescriptor ();
434
+ } else {
435
+ frameDescriptor = createFrameDescriptor ();
436
+ }
437
+ }
438
+ return frameDescriptor ;
439
+ }
440
+
441
+ @ TruffleBoundary
442
+ public RootCallTarget getRootCallTarget () {
443
+ if (rootNode != null ) {
444
+ return Truffle .getRuntime ().createCallTarget (rootNode );
445
+ }
446
+ return null ;
447
+ }
378
448
}
0 commit comments