41
41
package com .oracle .graal .python .builtins .objects .code ;
42
42
43
43
import java .util .ArrayList ;
44
+ import java .util .Arrays ;
45
+ import java .util .HashSet ;
46
+ import java .util .List ;
47
+ import java .util .Set ;
44
48
45
49
import com .oracle .graal .python .builtins .objects .object .PythonBuiltinObject ;
46
50
import com .oracle .graal .python .builtins .objects .type .PythonClass ;
47
51
import com .oracle .graal .python .nodes .ModuleRootNode ;
52
+ import com .oracle .graal .python .nodes .argument .ReadIndexedArgumentNode ;
53
+ import com .oracle .graal .python .nodes .argument .ReadKeywordNode ;
48
54
import com .oracle .graal .python .nodes .function .FunctionRootNode ;
49
55
import com .oracle .graal .python .nodes .generator .GeneratorFunctionRootNode ;
50
56
import com .oracle .graal .python .runtime .PythonCore ;
51
57
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
58
+ import com .oracle .truffle .api .nodes .NodeUtil ;
52
59
import com .oracle .truffle .api .nodes .RootNode ;
53
60
import com .oracle .truffle .api .source .SourceSection ;
54
61
@@ -70,24 +77,36 @@ public class PCode extends PythonBuiltinObject {
70
77
private final Object [] freevars ;
71
78
private final Object [] cellvars ;
72
79
73
- public PCode (PythonClass cls , RootNode result ) {
80
+ @ TruffleBoundary
81
+ public PCode (PythonClass cls , RootNode result , PythonCore core ) {
74
82
super (cls );
75
83
this .result = result ;
76
- this .argcount = -1 ;
77
- this .kwonlyargcount = -1 ;
78
- this .nlocals = -1 ;
84
+ // file stats
85
+ this .filename = getFileName (this .result );
86
+ this .name = getName (this .result );
87
+ this .firstlineno = getFirstLineno (this .result );
88
+ // arg stats
89
+ ArgStats argStats = getArgStats (this .result );
90
+ this .argcount = argStats .argCnt ;
91
+ this .kwonlyargcount = argStats .kwOnlyArgCnt ;
92
+ // var stats
93
+ String [] freevars = getFreeVars (this .result );
94
+ String [] cellvars = getCellVars (this .result );
95
+ Set <String > freeVarsSet = asSet (freevars );
96
+ Set <String > cellVarsSet = asSet (cellvars );
97
+ ArrayList <String > varNames = getVarNames (this .result , freeVarsSet , cellVarsSet , core );
98
+
99
+ this .freevars = freevars ;
100
+ this .cellvars = cellvars ;
101
+ this .varnames = varNames .toArray ();
102
+ this .nlocals = this .varnames .length ;
103
+
79
104
this .stacksize = -1 ;
80
105
this .flags = -1 ;
81
106
this .codestring = null ;
82
107
this .constants = null ;
83
108
this .names = null ;
84
- this .varnames = null ;
85
- this .filename = getFileName (this .result );
86
- this .name = getName (this .result );
87
- this .firstlineno = getFirstLineno (this .result );
88
109
this .lnotab = null ;
89
- this .freevars = getFreeVars (this .result );
90
- this .cellvars = getCellVars (this .result );
91
110
}
92
111
93
112
public PCode (PythonClass cls , int argcount , int kwonlyargcount , int nlocals , int stacksize ,
@@ -113,6 +132,10 @@ public PCode(PythonClass cls, int argcount, int kwonlyargcount, int nlocals, int
113
132
this .cellvars = cellvars ;
114
133
}
115
134
135
+ private static Set <String > asSet (String [] values ) {
136
+ return (values != null ) ? new HashSet <>(Arrays .asList (values )) : new HashSet <>();
137
+ }
138
+
116
139
private static String [] getFreeVars (RootNode rootNode ) {
117
140
if (rootNode instanceof FunctionRootNode ) {
118
141
return ((FunctionRootNode ) rootNode ).getFreeVars ();
@@ -144,7 +167,6 @@ private static String getFileName(RootNode rootNode) {
144
167
}
145
168
}
146
169
147
- @ TruffleBoundary
148
170
private static int getFirstLineno (RootNode rootNode ) {
149
171
SourceSection sourceSection = rootNode .getSourceSection ();
150
172
if (sourceSection == null ) {
@@ -166,14 +188,42 @@ private static String getName(RootNode rootNode) {
166
188
return name ;
167
189
}
168
190
169
- private static Object [] getVarNames (RootNode rootNode , PythonCore core ) {
191
+ private static ArrayList <String > getVarNames (RootNode rootNode , Set <String > freeVarsSet , Set <String > cellVarsSet , PythonCore core ) {
192
+ // tuple of names of arguments and local variables
170
193
ArrayList <String > variableNames = new ArrayList <>();
171
- for (Object ident : rootNode .getFrameDescriptor ().getIdentifiers ()) {
172
- if (ident instanceof String && core .getParser ().isIdentifier (core , (String ) ident )) {
173
- variableNames .add ((String ) ident );
194
+ for (Object identifier : rootNode .getFrameDescriptor ().getIdentifiers ()) {
195
+ if (identifier instanceof String ) {
196
+ String varName = (String ) identifier ;
197
+ if (core .getParser ().isIdentifier (core , varName ) && !freeVarsSet .contains (varName ) && !cellVarsSet .contains (varName )) {
198
+ variableNames .add (varName );
199
+ }
200
+ }
201
+ }
202
+ return variableNames ;
203
+ }
204
+
205
+ private final static class ArgStats {
206
+ public final int argCnt ;
207
+ private final int kwOnlyArgCnt ;
208
+
209
+ private ArgStats (int argCnt , int kwOnlyArgCnt ) {
210
+ this .argCnt = argCnt ;
211
+ this .kwOnlyArgCnt = kwOnlyArgCnt ;
212
+ }
213
+ }
214
+
215
+ private static ArgStats getArgStats (RootNode rootNode ) {
216
+ int argC = NodeUtil .findAllNodeInstances (rootNode , ReadIndexedArgumentNode .class ).size ();
217
+ int kwOnlyArgC = 0 ;
218
+ List <ReadKeywordNode > kwNodes = NodeUtil .findAllNodeInstances (rootNode , ReadKeywordNode .class );
219
+ for (ReadKeywordNode kwNode : kwNodes ) {
220
+ if (kwNode .canBePositional ()) {
221
+ argC ++;
222
+ } else {
223
+ kwOnlyArgC ++;
174
224
}
175
225
}
176
- return variableNames . toArray ( );
226
+ return new ArgStats ( argC , kwOnlyArgC );
177
227
}
178
228
179
229
public RootNode getRootNode () {
0 commit comments