Skip to content

Commit 78b722a

Browse files
committed
Move logic for creating code object into node.
1 parent cb99ea2 commit 78b722a

File tree

6 files changed

+213
-134
lines changed

6 files changed

+213
-134
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
import com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols;
8888
import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass;
8989
import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr;
90+
import com.oracle.graal.python.builtins.objects.code.CodeNodes;
9091
import com.oracle.graal.python.builtins.objects.code.PCode;
9192
import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes;
9293
import com.oracle.graal.python.builtins.objects.common.HashingStorage.DictEntry;
@@ -2422,8 +2423,9 @@ Object call(LazyPythonClass cls, int argcount, int kwonlyargcount,
24222423
String codestring, PTuple constants, PTuple names,
24232424
PTuple varnames, Object filename, Object name,
24242425
int firstlineno, String lnotab,
2425-
PTuple freevars, PTuple cellvars) {
2426-
return factory().createCode(cls, argcount, kwonlyargcount,
2426+
PTuple freevars, PTuple cellvars,
2427+
@Cached("create()") CodeNodes.CreateCodeNode createCodeNode) {
2428+
return createCodeNode.execute(cls, argcount, kwonlyargcount,
24272429
nlocals, stacksize, flags,
24282430
toBytes(codestring), constants.getArray(), names.getArray(),
24292431
varnames.getArray(), freevars.getArray(), cellvars.getArray(),
@@ -2438,11 +2440,12 @@ Object call(LazyPythonClass cls, int argcount, int kwonlyargcount,
24382440
PTuple varnames, Object filename, Object name,
24392441
int firstlineno, PBytes lnotab,
24402442
PTuple freevars, PTuple cellvars,
2441-
@Cached("create()") SequenceStorageNodes.ToByteArrayNode toByteArrayNode) {
2443+
@Cached("create()") SequenceStorageNodes.ToByteArrayNode toByteArrayNode,
2444+
@Cached("create()") CodeNodes.CreateCodeNode createCodeNode) {
24422445
byte[] codeBytes = toByteArrayNode.execute(codestring.getSequenceStorage());
24432446
byte[] lnotabBytes = toByteArrayNode.execute(lnotab.getSequenceStorage());
24442447

2445-
return factory().createCode(cls, argcount, kwonlyargcount,
2448+
return createCodeNode.execute(cls, argcount, kwonlyargcount,
24462449
nlocals, stacksize, flags,
24472450
codeBytes, constants.getArray(), names.getArray(),
24482451
varnames.getArray(), freevars.getArray(), cellvars.getArray(),

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@
2828
import static com.oracle.graal.python.runtime.exception.PythonErrorType.NotImplementedError;
2929
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
3030

31+
import java.io.ByteArrayOutputStream;
32+
import java.io.DataOutputStream;
33+
import java.io.IOException;
34+
import java.math.BigInteger;
35+
import java.util.Arrays;
36+
import java.util.HashMap;
3137
import java.util.List;
3238

3339
import com.oracle.graal.python.builtins.Builtin;
@@ -40,6 +46,8 @@
4046
import com.oracle.graal.python.builtins.objects.bytes.PByteArray;
4147
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
4248
import com.oracle.graal.python.builtins.objects.bytes.PIBytesLike;
49+
import com.oracle.graal.python.builtins.objects.code.CodeNodes;
50+
import com.oracle.graal.python.builtins.objects.code.CodeNodes.CreateCodeNode;
4351
import com.oracle.graal.python.builtins.objects.code.PCode;
4452
import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage;
4553
import com.oracle.graal.python.builtins.objects.common.HashingStorage;
@@ -67,12 +75,6 @@
6775
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
6876
import com.oracle.truffle.api.dsl.NodeFactory;
6977
import com.oracle.truffle.api.dsl.Specialization;
70-
import java.io.ByteArrayOutputStream;
71-
import java.io.DataOutputStream;
72-
import java.io.IOException;
73-
import java.math.BigInteger;
74-
import java.util.Arrays;
75-
import java.util.HashMap;
7678

7779
@CoreFunctions(defineModule = "marshal")
7880
public final class MarshalModuleBuiltins extends PythonBuiltins {
@@ -460,6 +462,7 @@ public abstract static class UnmarshallerNode extends PNodeWithContext {
460462
public abstract Object execute(byte[] dataBytes, int version);
461463

462464
@Child private HashingStorageNodes.SetItemNode setItemNode;
465+
@Child private CodeNodes.CreateCodeNode createCodeNode;
463466

464467
private int index;
465468
private byte[] data;
@@ -533,7 +536,7 @@ private PCode readCode(int depth) {
533536
int firstlineno = readInt();
534537
byte[] lnotab = readBytes();
535538

536-
return factory().createCode(PythonBuiltinClassType.PCode, argcount, kwonlyargcount,
539+
return ensureCreateCodeNode().execute(PythonBuiltinClassType.PCode, argcount, kwonlyargcount,
537540
nlocals, stacksize, flags, codestring, constants, names,
538541
varnames, freevars, cellvars, filename, name, firstlineno, lnotab);
539542
}
@@ -667,6 +670,14 @@ private Object readObject(int depth) {
667670
}
668671
}
669672

673+
private CreateCodeNode ensureCreateCodeNode() {
674+
if (createCodeNode == null) {
675+
CompilerDirectives.transferToInterpreterAndInvalidate();
676+
createCodeNode = insert(CodeNodes.CreateCodeNode.create());
677+
}
678+
return createCodeNode;
679+
}
680+
670681
@Specialization
671682
public Object readObject(byte[] dataBytes, @SuppressWarnings("unused") int version) {
672683
reset();
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package com.oracle.graal.python.builtins.objects.code;
2+
3+
import com.oracle.graal.python.PythonLanguage;
4+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
5+
import com.oracle.graal.python.builtins.objects.PNone;
6+
import com.oracle.graal.python.builtins.objects.cell.PCell;
7+
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes;
8+
import com.oracle.graal.python.builtins.objects.dict.PDict;
9+
import com.oracle.graal.python.builtins.objects.function.Arity;
10+
import com.oracle.graal.python.builtins.objects.function.PArguments;
11+
import com.oracle.graal.python.builtins.objects.function.PFunction;
12+
import com.oracle.graal.python.builtins.objects.str.PString;
13+
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
14+
import com.oracle.graal.python.nodes.ModuleRootNode;
15+
import com.oracle.graal.python.nodes.PNodeWithContext;
16+
import com.oracle.graal.python.runtime.PythonParser.ParserMode;
17+
import com.oracle.truffle.api.CompilerAsserts;
18+
import com.oracle.truffle.api.CompilerDirectives;
19+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
20+
import com.oracle.truffle.api.RootCallTarget;
21+
import com.oracle.truffle.api.Truffle;
22+
import com.oracle.truffle.api.frame.FrameDescriptor;
23+
import com.oracle.truffle.api.frame.FrameSlot;
24+
import com.oracle.truffle.api.frame.FrameSlotKind;
25+
import com.oracle.truffle.api.frame.MaterializedFrame;
26+
import com.oracle.truffle.api.frame.VirtualFrame;
27+
import com.oracle.truffle.api.nodes.RootNode;
28+
import com.oracle.truffle.api.source.Source;
29+
30+
public abstract class CodeNodes {
31+
32+
public static class CreateCodeNode extends PNodeWithContext {
33+
34+
@Child private HashingStorageNodes.GetItemNode getItemNode;
35+
36+
@TruffleBoundary
37+
public PCode execute(LazyPythonClass cls, int argcount, int kwonlyargcount,
38+
int nlocals, int stacksize, int flags,
39+
byte[] codestring, Object[] constants, Object[] names,
40+
Object[] varnames, Object[] freevars, Object[] cellvars,
41+
String filename, String name, int firstlineno,
42+
byte[] lnotab) {
43+
44+
RootCallTarget callTarget = null;
45+
46+
// Derive a new call target from the code string, if we can
47+
RootNode rootNode = null;
48+
if (codestring.length > 0) {
49+
if ((flags & PCode.FLAG_MODULE) == 0) {
50+
// we're looking for the function, not the module
51+
String funcdef;
52+
funcdef = createFuncdef(codestring, freevars, name);
53+
54+
rootNode = (RootNode) getCore().getParser().parse(ParserMode.File, getCore(), Source.newBuilder(PythonLanguage.ID, funcdef, name).build(), null);
55+
Object[] args = PArguments.create();
56+
PDict globals = factory().createDict();
57+
PArguments.setGlobals(args, globals);
58+
Truffle.getRuntime().createCallTarget(rootNode).call(args);
59+
Object function = ensureGetItemNode().execute(globals.getDictStorage(), name);
60+
if (function instanceof PFunction) {
61+
rootNode = ((PFunction) function).getFunctionRootNode();
62+
} else {
63+
throw raise(PythonBuiltinClassType.ValueError, "got an invalid codestring trying to create a function code object");
64+
}
65+
} else {
66+
MaterializedFrame frame = null;
67+
if (freevars.length > 0) {
68+
FrameDescriptor frameDescriptor = new FrameDescriptor();
69+
frame = Truffle.getRuntime().createMaterializedFrame(new Object[0], frameDescriptor);
70+
for (int i = 0; i < freevars.length; i++) {
71+
Object ident = freevars[i];
72+
FrameSlot slot = frameDescriptor.addFrameSlot(ident);
73+
frameDescriptor.setFrameSlotKind(slot, FrameSlotKind.Object);
74+
frame.setObject(slot, new PCell());
75+
}
76+
}
77+
rootNode = (RootNode) getCore().getParser().parse(ParserMode.File, getCore(), Source.newBuilder(PythonLanguage.ID, new String(codestring), name).build(), frame);
78+
assert rootNode instanceof ModuleRootNode;
79+
}
80+
callTarget = Truffle.getRuntime().createCallTarget(rootNode);
81+
} else {
82+
callTarget = Truffle.getRuntime().createCallTarget(new RootNode(PythonLanguage.getCurrent()) {
83+
@Override
84+
public Object execute(VirtualFrame frame) {
85+
return PNone.NONE;
86+
}
87+
});
88+
}
89+
90+
Arity arity = createArity(flags, argcount, kwonlyargcount, varnames);
91+
92+
return factory().createCode(cls, callTarget, arity, nlocals, stacksize, flags, codestring, constants, names, varnames, freevars, cellvars, filename, name, firstlineno, lnotab);
93+
}
94+
95+
private static String createFuncdef(byte[] codestring, Object[] freevars, String name) {
96+
CompilerAsserts.neverPartOfCompilation();
97+
if (freevars.length > 0) {
98+
// we build an outer function to provide the initial scoping
99+
String outernme = "_____" + System.nanoTime();
100+
StringBuilder sb = new StringBuilder();
101+
sb.append("def ").append(outernme).append("():\n");
102+
for (Object freevar : freevars) {
103+
String v;
104+
if (freevar instanceof PString) {
105+
v = ((PString) freevar).getValue();
106+
} else if (freevar instanceof String) {
107+
v = (String) freevar;
108+
} else {
109+
continue;
110+
}
111+
sb.append(" ").append(v).append(" = None\n");
112+
}
113+
sb.append(" global ").append(name).append("\n");
114+
sb.append(" ").append(new String(codestring));
115+
sb.append("\n\n").append(outernme).append("()");
116+
return sb.toString();
117+
} else {
118+
return new String(codestring);
119+
}
120+
}
121+
122+
private static Arity createArity(int flags, int argcount, int kwonlyargcount, Object[] varnames) {
123+
CompilerAsserts.neverPartOfCompilation();
124+
char paramNom = 'A';
125+
String[] paramNames = new String[argcount];
126+
for (int i = 0; i < paramNames.length; i++) {
127+
if (varnames.length > i) {
128+
Object varname = varnames[i];
129+
if (varname instanceof String) {
130+
paramNames[i] = (String) varname;
131+
continue;
132+
}
133+
}
134+
paramNames[i] = Character.toString(paramNom++);
135+
}
136+
String[] kwNames = new String[kwonlyargcount];
137+
for (int i = 0; i < kwNames.length; i++) {
138+
if (varnames.length > i + argcount) {
139+
Object varname = varnames[i + argcount];
140+
if (varname instanceof String) {
141+
kwNames[i] = (String) varname;
142+
continue;
143+
}
144+
}
145+
kwNames[i] = Character.toString(paramNom++);
146+
}
147+
return new Arity(PCode.takesVarKeywordArgs(flags), PCode.takesVarArgs(flags) ? argcount : -1, !PCode.takesVarArgs(flags) && kwonlyargcount > 0, paramNames, kwNames);
148+
}
149+
150+
private HashingStorageNodes.GetItemNode ensureGetItemNode() {
151+
if (getItemNode == null) {
152+
CompilerDirectives.transferToInterpreterAndInvalidate();
153+
getItemNode = insert(HashingStorageNodes.GetItemNode.create());
154+
}
155+
return getItemNode;
156+
}
157+
158+
public static CreateCodeNode create() {
159+
return new CreateCodeNode();
160+
}
161+
}
162+
}

0 commit comments

Comments
 (0)