Skip to content

Commit 80f2f16

Browse files
committed
PCode: extract co_nlocals, co_varnames
1 parent 88f64d0 commit 80f2f16

File tree

3 files changed

+75
-21
lines changed

3 files changed

+75
-21
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ protected Object get(PCode self) {
115115
public abstract static class GetArgCountNode extends PythonBuiltinNode {
116116
@Specialization
117117
protected Object get(PCode self) {
118-
return PNotImplemented.NOT_IMPLEMENTED;
118+
return self.getArgcount();
119119
}
120120
}
121121

@@ -124,7 +124,7 @@ protected Object get(PCode self) {
124124
public abstract static class GetKnownlyArgCountNode extends PythonBuiltinNode {
125125
@Specialization
126126
protected Object get(PCode self) {
127-
return PNotImplemented.NOT_IMPLEMENTED;
127+
return self.getKwonlyargcount();
128128
}
129129
}
130130

@@ -133,7 +133,7 @@ protected Object get(PCode self) {
133133
public abstract static class GetNLocalsNode extends PythonBuiltinNode {
134134
@Specialization
135135
protected Object get(PCode self) {
136-
return PNotImplemented.NOT_IMPLEMENTED;
136+
return self.getNlocals();
137137
}
138138
}
139139

@@ -187,7 +187,11 @@ protected Object get(PCode self) {
187187
public abstract static class GetVarNamesNode extends PythonBuiltinNode {
188188
@Specialization
189189
protected Object get(PCode self) {
190-
return PNotImplemented.NOT_IMPLEMENTED;
190+
Object[] varNames = self.getVarnames();
191+
if (varNames != null) {
192+
return factory().createTuple(varNames);
193+
}
194+
return PNone.NONE;
191195
}
192196
}
193197

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,21 @@
4141
package com.oracle.graal.python.builtins.objects.code;
4242

4343
import java.util.ArrayList;
44+
import java.util.Arrays;
45+
import java.util.HashSet;
46+
import java.util.List;
47+
import java.util.Set;
4448

4549
import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
4650
import com.oracle.graal.python.builtins.objects.type.PythonClass;
4751
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;
4854
import com.oracle.graal.python.nodes.function.FunctionRootNode;
4955
import com.oracle.graal.python.nodes.generator.GeneratorFunctionRootNode;
5056
import com.oracle.graal.python.runtime.PythonCore;
5157
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
58+
import com.oracle.truffle.api.nodes.NodeUtil;
5259
import com.oracle.truffle.api.nodes.RootNode;
5360
import com.oracle.truffle.api.source.SourceSection;
5461

@@ -70,24 +77,36 @@ public class PCode extends PythonBuiltinObject {
7077
private final Object[] freevars;
7178
private final Object[] cellvars;
7279

73-
public PCode(PythonClass cls, RootNode result) {
80+
@TruffleBoundary
81+
public PCode(PythonClass cls, RootNode result, PythonCore core) {
7482
super(cls);
7583
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+
79104
this.stacksize = -1;
80105
this.flags = -1;
81106
this.codestring = null;
82107
this.constants = null;
83108
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);
88109
this.lnotab = null;
89-
this.freevars = getFreeVars(this.result);
90-
this.cellvars = getCellVars(this.result);
91110
}
92111

93112
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
113132
this.cellvars = cellvars;
114133
}
115134

135+
private static Set<String> asSet(String[] values) {
136+
return (values != null) ? new HashSet<>(Arrays.asList(values)) : new HashSet<>();
137+
}
138+
116139
private static String[] getFreeVars(RootNode rootNode) {
117140
if (rootNode instanceof FunctionRootNode) {
118141
return ((FunctionRootNode) rootNode).getFreeVars();
@@ -144,7 +167,6 @@ private static String getFileName(RootNode rootNode) {
144167
}
145168
}
146169

147-
@TruffleBoundary
148170
private static int getFirstLineno(RootNode rootNode) {
149171
SourceSection sourceSection = rootNode.getSourceSection();
150172
if (sourceSection == null) {
@@ -166,14 +188,42 @@ private static String getName(RootNode rootNode) {
166188
return name;
167189
}
168190

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
170193
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++;
174224
}
175225
}
176-
return variableNames.toArray();
226+
return new ArgStats(argC, kwOnlyArgC);
177227
}
178228

179229
public RootNode getRootNode() {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/object/PythonObjectFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ public PBuffer createBuffer(Object iterable) {
699699
}
700700

701701
public Object createCode(RootNode result) {
702-
return trace(new PCode(lookupClass(PythonBuiltinClassType.PCode), result));
702+
return trace(new PCode(lookupClass(PythonBuiltinClassType.PCode), result, getCore()));
703703
}
704704

705705
public Object createCode(PythonClass cls, int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, String codestring, Object constants, Object names, Object[] varnames,

0 commit comments

Comments
 (0)