Skip to content

Commit 3f9fa9d

Browse files
committed
GR-20184: add builtin truffle_co_globals Code object attribute (returns a tuple of the global variable names referenced by the code object)
1 parent fad312f commit 3f9fa9d

File tree

4 files changed

+82
-2
lines changed

4 files changed

+82
-2
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_code.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ def a_function():
4444

4545
def wrapper():
4646
values = []
47+
global a_global
48+
49+
a_global = set([11, 12])
4750

4851
def my_func(arg_l, kwarg_case="empty set", kwarg_other=19):
4952
loc_1 = set(values)
@@ -64,6 +67,9 @@ def inner_func():
6467
return my_func
6568

6669

70+
a_global = 10
71+
72+
6773
def test_name():
6874
assert a_function.__code__.co_name == "a_function"
6975

@@ -94,7 +100,7 @@ def test_code_attributes():
94100
assert set(code.co_varnames) == {'arg_l', 'kwarg_case', 'kwarg_other', 'loc_1', 'loc_3', 'inner_func'}
95101
assert code.co_filename.endswith("test_code.py")
96102
assert code.co_name == "my_func"
97-
assert code.co_firstlineno == 48
103+
assert code.co_firstlineno == 51
98104
# assert code.co_lnotab == b'\x00\x01\x0c\x01\x0c\x01\x06\x02\x15\x03\x03\x01\x0e\x01\r\x01\x05\x02'
99105
assert set(code.co_freevars) == {'values'}
100106
assert set(code.co_cellvars) == {'kwarg_other', 'loc_2'}
@@ -161,3 +167,11 @@ def test_module_code():
161167
# assert code.co_lnotab == b''
162168
assert code.co_freevars == tuple()
163169
assert code.co_cellvars == tuple()
170+
171+
172+
def test_get_globals():
173+
import sys
174+
code = wrapper.__code__
175+
if sys.implementation.name == 'graalpython':
176+
# print(">>> ", code.truffle_co_globals)
177+
assert set(code.truffle_co_globals) == {'a_global'}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
8888
import com.oracle.graal.python.builtins.PythonBuiltins;
8989
import com.oracle.graal.python.builtins.modules.BuiltinFunctionsFactory.GetAttrNodeFactory;
90+
import com.oracle.graal.python.builtins.modules.BuiltinFunctionsFactory.GlobalsNodeFactory;
9091
import com.oracle.graal.python.builtins.objects.PNone;
9192
import com.oracle.graal.python.builtins.objects.PNotImplemented;
9293
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
@@ -1905,7 +1906,7 @@ String inputPrompt(String prompt) {
19051906

19061907
@Builtin(name = "globals", minNumOfPositionalArgs = 0)
19071908
@GenerateNodeFactory
1908-
abstract static class GlobalsNode extends PythonBuiltinNode {
1909+
public abstract static class GlobalsNode extends PythonBuiltinNode {
19091910
@Child private ReadCallerFrameNode readCallerFrameNode = ReadCallerFrameNode.create();
19101911

19111912
private final ConditionProfile condProfile = ConditionProfile.createBinaryProfile();
@@ -1932,6 +1933,10 @@ public Object globals(VirtualFrame frame,
19321933
return globals;
19331934
}
19341935
}
1936+
1937+
public static GlobalsNode create() {
1938+
return GlobalsNodeFactory.create(null);
1939+
}
19351940
}
19361941

19371942
@Builtin(name = "locals", minNumOfPositionalArgs = 0)

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,25 @@
2626

2727
package com.oracle.graal.python.builtins.objects.code;
2828

29+
import java.util.ArrayList;
2930
import java.util.List;
3031

3132
import com.oracle.graal.python.builtins.Builtin;
3233
import com.oracle.graal.python.builtins.CoreFunctions;
3334
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
3435
import com.oracle.graal.python.builtins.PythonBuiltins;
36+
import com.oracle.graal.python.builtins.modules.BuiltinFunctions.GlobalsNode;
3537
import com.oracle.graal.python.builtins.objects.PNone;
38+
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.ContainsKeyNode;
39+
import com.oracle.graal.python.builtins.objects.dict.PDict;
3640
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
3741
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
3842
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
43+
import com.oracle.truffle.api.dsl.Cached;
3944
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
4045
import com.oracle.truffle.api.dsl.NodeFactory;
4146
import com.oracle.truffle.api.dsl.Specialization;
47+
import com.oracle.truffle.api.frame.VirtualFrame;
4248

4349
@CoreFunctions(extendClasses = PythonBuiltinClassType.PCode)
4450
public class CodeBuiltins extends PythonBuiltins {
@@ -218,6 +224,28 @@ protected Object get(PCode self) {
218224
}
219225
}
220226

227+
@Builtin(name = "truffle_co_globals", minNumOfPositionalArgs = 1, isGetter = true)
228+
@GenerateNodeFactory
229+
public abstract static class GetGlobalVarNamesNode extends PythonBuiltinNode {
230+
@Specialization
231+
protected Object get(VirtualFrame frame, PCode self,
232+
@Cached GlobalsNode globalsNode,
233+
@Cached ContainsKeyNode containsKeyNode) {
234+
Object[] varNames = self.getGlobalAndBuiltinVarNames();
235+
if (varNames != null) {
236+
PDict globals = (PDict) globalsNode.execute(frame);
237+
ArrayList<Object> vars = new ArrayList<>();
238+
for (Object name : varNames) {
239+
if (containsKeyNode.execute(frame, globals.getDictStorage(), name)) {
240+
vars.add(name);
241+
}
242+
}
243+
return factory().createTuple(vars.toArray());
244+
}
245+
return PNone.NONE;
246+
}
247+
}
248+
221249
@Builtin(name = "co_lnotab", minNumOfPositionalArgs = 1, isGetter = true)
222250
@GenerateNodeFactory
223251
public abstract static class GetLNoTabNode extends PythonBuiltinNode {

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import java.util.ArrayList;
4444
import java.util.Arrays;
4545
import java.util.HashSet;
46+
import java.util.List;
4647
import java.util.Set;
4748

4849
import com.oracle.graal.python.PythonLanguage;
@@ -53,7 +54,11 @@
5354
import com.oracle.graal.python.nodes.PRootNode;
5455
import com.oracle.graal.python.nodes.argument.ReadVarArgsNode;
5556
import com.oracle.graal.python.nodes.argument.ReadVarKeywordsNode;
57+
import com.oracle.graal.python.nodes.frame.DeleteGlobalNode;
5658
import com.oracle.graal.python.nodes.frame.FrameSlotIDs;
59+
import com.oracle.graal.python.nodes.frame.GlobalNode;
60+
import com.oracle.graal.python.nodes.frame.ReadGlobalOrBuiltinNode;
61+
import com.oracle.graal.python.nodes.frame.WriteGlobalNode;
5762
import com.oracle.graal.python.nodes.function.FunctionRootNode;
5863
import com.oracle.graal.python.nodes.generator.GeneratorFunctionRootNode;
5964
import com.oracle.truffle.api.CompilerDirectives;
@@ -104,6 +109,8 @@ public final class PCode extends PythonBuiltinObject {
104109
private Object[] freevars;
105110
// tuple of names of cell variables (referenced by containing scopes)
106111
private Object[] cellvars;
112+
// is a tuple containing the names of the global variables accessed from this code object
113+
private Object[] globalAndBuiltinVarNames;
107114

108115
public PCode(LazyPythonClass cls, RootCallTarget callTarget) {
109116
super(cls);
@@ -242,6 +249,25 @@ private static Object[] extractVarnames(RootNode rootNode, String[] parameterIds
242249
return varNameList.toArray();
243250
}
244251

252+
@TruffleBoundary
253+
private static Object[] extractGlobalVarnames(RootNode rootNode) {
254+
RootNode funcRootNode = (rootNode instanceof GeneratorFunctionRootNode) ? ((GeneratorFunctionRootNode) rootNode).getFunctionRootNode() : rootNode;
255+
Set<Object> varNameList = new HashSet<>();
256+
257+
List<GlobalNode> globalNodes = NodeUtil.findAllNodeInstances(funcRootNode, GlobalNode.class);
258+
for (GlobalNode node : globalNodes) {
259+
if (node instanceof ReadGlobalOrBuiltinNode) {
260+
varNameList.add(((ReadGlobalOrBuiltinNode) node).getAttributeId());
261+
} else if (node instanceof WriteGlobalNode) {
262+
varNameList.add(((WriteGlobalNode) node).getAttributeId());
263+
} else if (node instanceof DeleteGlobalNode) {
264+
varNameList.add(((DeleteGlobalNode) node).getAttributeId());
265+
}
266+
}
267+
268+
return varNameList.toArray();
269+
}
270+
245271
@TruffleBoundary
246272
private static int extractFlags(RootNode rootNode) {
247273
int flags = 0;
@@ -371,6 +397,13 @@ public byte[] getCodestring() {
371397
return codestring;
372398
}
373399

400+
public Object[] getGlobalAndBuiltinVarNames() {
401+
if (globalAndBuiltinVarNames == null) {
402+
this.globalAndBuiltinVarNames = extractGlobalVarnames(getRootNode());
403+
}
404+
return globalAndBuiltinVarNames;
405+
}
406+
374407
public Object[] getConstants() {
375408
return constants;
376409
}

0 commit comments

Comments
 (0)