Skip to content

Commit 9c54885

Browse files
committed
create a frame to capture the free vars when creating a code object from a code string (really a source string).
- add support for lambdas as well
1 parent 324cb4b commit 9c54885

File tree

1 file changed

+27
-30
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code

1 file changed

+27
-30
lines changed

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

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -131,33 +131,20 @@ private PCode createCode(LazyPythonClass cls, int argcount, int kwonlyargcount,
131131
PythonCore core = PythonLanguage.getCore();
132132
if ((flags & PCode.FLAG_MODULE) == 0) {
133133
// we're looking for the function, not the module
134-
String funcdef;
135-
funcdef = createFuncdef(codestring, freevars, name);
136-
rootNode = (RootNode) core.getParser().parse(ParserMode.File, core, Source.newBuilder(PythonLanguage.ID, funcdef, name).build(), null);
134+
String funcdef = createFuncdef(codestring, freevars, name);
135+
MaterializedFrame frame = getFrameForFreeVars(freevars, argcount);
136+
rootNode = (RootNode) core.getParser().parse(ParserMode.File, core, Source.newBuilder(PythonLanguage.ID, funcdef, name).build(), frame);
137137
Object[] args = PArguments.create();
138138
PDict globals = factory.createDict();
139139
PArguments.setGlobals(args, globals);
140140
Object function = InvokeNode.invokeUncached(Truffle.getRuntime().createCallTarget(rootNode), args);
141-
if (function == PNone.NONE) {
142-
function = ensureGetItemNode().execute(null, globals.getDictStorage(), name);
143-
}
144141
if (function instanceof PFunction) {
145142
rootNode = ((PFunction) function).getFunctionRootNode();
146143
} else {
147144
throw PRaiseNode.getUncached().raise(PythonBuiltinClassType.ValueError, "got an invalid codestring trying to create a function code object");
148145
}
149146
} else {
150-
MaterializedFrame frame = null;
151-
if (freevars.length > 0) {
152-
FrameDescriptor frameDescriptor = new FrameDescriptor();
153-
frame = Truffle.getRuntime().createMaterializedFrame(new Object[0], frameDescriptor);
154-
for (int i = 0; i < freevars.length; i++) {
155-
Object ident = freevars[i];
156-
FrameSlot slot = frameDescriptor.addFrameSlot(ident);
157-
frameDescriptor.setFrameSlotKind(slot, FrameSlotKind.Object);
158-
frame.setObject(slot, new PCell(Truffle.getRuntime().createAssumption("cell is effectively final")));
159-
}
160-
}
147+
MaterializedFrame frame = getFrameForFreeVars(freevars, argcount);
161148
rootNode = (RootNode) core.getParser().parse(ParserMode.File, core, Source.newBuilder(PythonLanguage.ID, new String(codestring), name).build(), frame);
162149
assert rootNode instanceof ModuleRootNode;
163150
}
@@ -186,30 +173,40 @@ public boolean isPythonInternal() {
186173
return factory.createCode(cls, callTarget, signature, nlocals, stacksize, flags, codestring, constants, names, varnames, freevars, cellvars, filename, name, firstlineno, lnotab);
187174
}
188175

176+
private MaterializedFrame getFrameForFreeVars(Object[] freevars, int argcount) {
177+
MaterializedFrame frame = null;
178+
if (freevars.length > 0) {
179+
FrameDescriptor frameDescriptor = new FrameDescriptor();
180+
frame = Truffle.getRuntime().createMaterializedFrame(PArguments.create(argcount), frameDescriptor);
181+
for (int i = 0; i < freevars.length; i++) {
182+
Object ident = freevars[i];
183+
FrameSlot slot = frameDescriptor.addFrameSlot(ident);
184+
frameDescriptor.setFrameSlotKind(slot, FrameSlotKind.Object);
185+
frame.setObject(slot, new PCell(Truffle.getRuntime().createAssumption("cell is effectively final")));
186+
}
187+
}
188+
return frame;
189+
}
190+
189191
private static String createFuncdef(byte[] codestring, Object[] freevars, String name) {
190192
CompilerAsserts.neverPartOfCompilation();
193+
String codeStr = new String(codestring);
194+
boolean isLambda = codeStr.trim().startsWith("lambda");
191195
if (freevars.length > 0) {
192196
// we build an outer function to provide the initial scoping
193197
String outernme = "_____" + System.nanoTime();
194198
StringBuilder sb = new StringBuilder();
195199
sb.append("def ").append(outernme).append("():\n");
196-
for (Object freevar : freevars) {
197-
String v;
198-
if (freevar instanceof PString) {
199-
v = ((PString) freevar).getValue();
200-
} else if (freevar instanceof String) {
201-
v = (String) freevar;
202-
} else {
203-
continue;
204-
}
205-
sb.append(" ").append(v).append(" = None\n");
200+
if (isLambda) {
201+
sb.append(" ").append("return ").append(codeStr);
202+
} else {
203+
sb.append(" ").append(codeStr).append("\n");
204+
sb.append(" ").append("return ").append(name);
206205
}
207-
sb.append(" global ").append(name).append("\n");
208-
sb.append(" ").append(new String(codestring));
209206
sb.append("\n\n").append(outernme).append("()");
210207
return sb.toString();
211208
} else {
212-
return new String(codestring);
209+
return codeStr;
213210
}
214211
}
215212

0 commit comments

Comments
 (0)