4545import java .util .List ;
4646import java .util .Set ;
4747
48+ import com .oracle .graal .python .builtins .objects .function .Arity ;
4849import com .oracle .graal .python .builtins .objects .object .PythonBuiltinObject ;
4950import com .oracle .graal .python .builtins .objects .type .PythonClass ;
5051import com .oracle .graal .python .nodes .ModuleRootNode ;
5758import com .oracle .graal .python .nodes .generator .GeneratorFunctionRootNode ;
5859import com .oracle .graal .python .runtime .PythonCore ;
5960import 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 ;
6064import com .oracle .truffle .api .nodes .Node ;
6165import com .oracle .truffle .api .nodes .NodeUtil ;
6266import com .oracle .truffle .api .nodes .RootNode ;
6367import com .oracle .truffle .api .source .SourceSection ;
6468
6569public 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+
6674 private final RootNode rootNode ;
6775 private final PythonCore core ;
6876
@@ -101,6 +109,11 @@ public class PCode extends PythonBuiltinObject {
101109 // tuple of names of cell variables (referenced by containing scopes)
102110 private Object [] cellvars ;
103111
112+ // internal cache for keyword names
113+ private Arity .KeywordName [] keywordNames ;
114+ // internal cache for the FrameDescriptor
115+ private FrameDescriptor frameDescriptor ;
116+
104117 public PCode (PythonClass cls , RootNode rootNode , PythonCore core ) {
105118 super (cls );
106119 this .rootNode = rootNode ;
@@ -223,17 +236,17 @@ private void extractArgStats() {
223236 this .flags = 0 ;
224237 RootNode funcRootNode = rootNode ;
225238 if (funcRootNode instanceof GeneratorFunctionRootNode ) {
226- flags |= (1 << 5 );
239+ flags |= (1 << FLAG_POS_GENERATOR );
227240 funcRootNode = ((GeneratorFunctionRootNode ) funcRootNode ).getFunctionRootNode ();
228241 }
229242
230243 // 0x04 - *arguments
231244 if (NodeUtil .findAllNodeInstances (funcRootNode , ReadVarArgsNode .class ).size () == 1 ) {
232- flags |= (1 << 2 );
245+ flags |= (1 << FLAG_POS_VAR_ARGS );
233246 }
234247 // 0x08 - **keywords
235248 if (NodeUtil .findAllNodeInstances (funcRootNode , ReadVarKeywordsNode .class ).size () == 1 ) {
236- flags |= (1 << 3 );
249+ flags |= (1 << FLAG_POS_VAR_KW_ARGS );
237250 }
238251
239252 this .freevars = extractFreeVars (rootNode );
@@ -242,6 +255,7 @@ private void extractArgStats() {
242255 Set <String > cellVarsSet = asSet ((String []) cellvars );
243256
244257 List <ReadKeywordNode > readKeywordNodes = NodeUtil .findAllNodeInstances (funcRootNode , ReadKeywordNode .class );
258+ keywordNames = new Arity .KeywordName [readKeywordNodes .size ()];
245259 List <ReadIndexedArgumentNode > readIndexedArgumentNodes = NodeUtil .findAllNodeInstances (funcRootNode , ReadIndexedArgumentNode .class );
246260
247261 Set <String > kwNames = getKeywordArgumentNames (readKeywordNodes );
@@ -254,7 +268,9 @@ private void extractArgStats() {
254268 this .argcount = readIndexedArgumentNodes .size ();
255269 this .kwonlyargcount = 0 ;
256270
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 ());
258274 if (!kwNode .canBePositional ()) {
259275 kwonlyargcount ++;
260276 }
@@ -375,4 +391,58 @@ public Object getNames() {
375391 public Object getLnotab () {
376392 return lnotab ;
377393 }
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+ }
378448}
0 commit comments