Skip to content

Commit f32b10b

Browse files
committed
use an overly complicated solution to recreate a function root node
1 parent fbbb9c1 commit f32b10b

File tree

1 file changed

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

1 file changed

+60
-8
lines changed

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

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,15 @@
4747
import java.util.Set;
4848

4949
import com.oracle.graal.python.PythonLanguage;
50+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
5051
import com.oracle.graal.python.builtins.objects.cell.PCell;
52+
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
53+
import com.oracle.graal.python.builtins.objects.dict.PDict;
5154
import com.oracle.graal.python.builtins.objects.function.Arity;
55+
import com.oracle.graal.python.builtins.objects.function.PArguments;
56+
import com.oracle.graal.python.builtins.objects.function.PFunction;
5257
import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject;
58+
import com.oracle.graal.python.builtins.objects.str.PString;
5359
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
5460
import com.oracle.graal.python.nodes.ModuleRootNode;
5561
import com.oracle.graal.python.nodes.PRootNode;
@@ -127,6 +133,7 @@ public PCode(LazyPythonClass cls, RootCallTarget callTarget) {
127133
}
128134
}
129135

136+
@TruffleBoundary
130137
public PCode(LazyPythonClass cls, int argcount, int kwonlyargcount,
131138
int nlocals, int stacksize, int flags,
132139
byte[] codestring, Object[] constants, Object[] names,
@@ -150,15 +157,60 @@ public PCode(LazyPythonClass cls, int argcount, int kwonlyargcount,
150157
this.cellvars = cellvars;
151158

152159
// Derive a new call target from the code string, if we can
153-
FrameDescriptor frameDescriptor = new FrameDescriptor();
154-
MaterializedFrame frame = Truffle.getRuntime().createMaterializedFrame(new Object[0], frameDescriptor);
155-
for (int i = 0; i < freevars.length; i++) {
156-
Object ident = freevars[i];
157-
FrameSlot slot = frameDescriptor.addFrameSlot(ident);
158-
frameDescriptor.setFrameSlotKind(slot, FrameSlotKind.Object);
159-
frame.setObject(slot, new PCell());
160+
RootNode rootNode = null;
161+
if ((flags & FLAG_MODULE) == 0) {
162+
// we're looking for the function, not the module
163+
String funcdef;
164+
if (freevars.length > 0) {
165+
// we build an outer function to provide the initial scoping
166+
String outernme = "_____" + System.nanoTime();
167+
StringBuilder sb = new StringBuilder();
168+
sb.append("def ").append(outernme).append("():\n");
169+
for (Object freevar : freevars) {
170+
String v;
171+
if (freevar instanceof PString) {
172+
v = ((PString) freevar).getValue();
173+
} else if (freevar instanceof String) {
174+
v = (String) freevar;
175+
} else {
176+
continue;
177+
}
178+
sb.append(" ").append(v).append(" = None\n");
179+
}
180+
sb.append(" global ").append(name).append("\n");
181+
sb.append(" ").append(new String(codestring));
182+
sb.append("\n\n").append(outernme).append("()");
183+
funcdef = sb.toString();
184+
} else {
185+
funcdef = new String(codestring);
186+
}
187+
188+
rootNode = (RootNode) PythonLanguage.getCore().getParser().parse(ParserMode.File, PythonLanguage.getCore(), Source.newBuilder("python", funcdef, name).build(), null);
189+
Object[] args = PArguments.create();
190+
PDict globals = PythonLanguage.getCore().factory().createDict();
191+
PArguments.setGlobals(args, globals);
192+
Truffle.getRuntime().createCallTarget(rootNode).call(args);
193+
Object function = globals.getDictStorage().getItem(name, HashingStorage.getSlowPathEquivalence(name));
194+
if (function instanceof PFunction) {
195+
rootNode = ((PFunction) function).getFunctionRootNode();
196+
} else {
197+
throw PythonLanguage.getCore().raise(PythonBuiltinClassType.ValueError, "got an invalid codestring trying to create a function code object");
198+
}
199+
} else {
200+
MaterializedFrame frame = null;
201+
if (freevars.length > 0) {
202+
FrameDescriptor frameDescriptor = new FrameDescriptor();
203+
frame = Truffle.getRuntime().createMaterializedFrame(new Object[0], frameDescriptor);
204+
for (int i = 0; i < freevars.length; i++) {
205+
Object ident = freevars[i];
206+
FrameSlot slot = frameDescriptor.addFrameSlot(ident);
207+
frameDescriptor.setFrameSlotKind(slot, FrameSlotKind.Object);
208+
frame.setObject(slot, new PCell());
209+
}
210+
}
211+
rootNode = (RootNode) PythonLanguage.getCore().getParser().parse(ParserMode.File, PythonLanguage.getCore(), Source.newBuilder("python", new String(codestring), name).build(), frame);
212+
assert rootNode instanceof ModuleRootNode;
160213
}
161-
RootNode rootNode = (RootNode) PythonLanguage.getCore().getParser().parse(ParserMode.File, PythonLanguage.getCore(), Source.newBuilder("python", new String(codestring), name).build(), frame);
162214
this.callTarget = Truffle.getRuntime().createCallTarget(rootNode);
163215

164216
char paramNom = 'A';

0 commit comments

Comments
 (0)