Skip to content

Commit ad69966

Browse files
committed
[GR-17036] Use the new RootBodyTag.
Initial commit
1 parent 34e60f0 commit ad69966

File tree

247 files changed

+71982
-70919
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

247 files changed

+71982
-70919
lines changed
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
/*
2+
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.test.interop;
42+
43+
import com.oracle.graal.python.nodes.PNode;
44+
import com.oracle.graal.python.nodes.function.InnerRootNode;
45+
import com.oracle.graal.python.test.PythonTests;
46+
import com.oracle.truffle.api.frame.VirtualFrame;
47+
import com.oracle.truffle.api.instrumentation.EventContext;
48+
import com.oracle.truffle.api.instrumentation.ExecutionEventListener;
49+
import com.oracle.truffle.api.instrumentation.InstrumentableNode;
50+
import com.oracle.truffle.api.instrumentation.SourceSectionFilter;
51+
import com.oracle.truffle.api.instrumentation.StandardTags;
52+
import com.oracle.truffle.api.instrumentation.TruffleInstrument;
53+
import com.oracle.truffle.api.interop.InteropLibrary;
54+
import com.oracle.truffle.api.library.LibraryFactory;
55+
import com.oracle.truffle.api.nodes.Node;
56+
import java.util.HashMap;
57+
import org.graalvm.polyglot.Context;
58+
import org.graalvm.polyglot.Engine;
59+
import org.graalvm.polyglot.Instrument;
60+
import org.graalvm.polyglot.Source;
61+
import org.junit.Assert;
62+
import static org.junit.Assert.assertTrue;
63+
import static org.junit.Assert.assertFalse;
64+
import org.junit.Test;
65+
66+
public class StandardTagsTests extends PythonTests {
67+
68+
static final InteropLibrary INTEROP = LibraryFactory.resolve(InteropLibrary.class).getUncached();
69+
70+
private static Context newContext(Engine engine) {
71+
return Context.newBuilder().allowExperimentalOptions(true).allowAllAccess(true).engine(engine).build();
72+
}
73+
74+
@Test
75+
public void testRootBodyTagModule() throws Exception {
76+
String code = "import time\n" + "time.gmtime()\n";
77+
checkRootTagAndRootBodyTag(code);
78+
}
79+
80+
@Test
81+
public void testRootBodyTagGenerator01() throws Exception {
82+
String code = "def test():\n" + " yield 22\n" + "for i in test():\n" + " i\n";
83+
checkRootTagAndRootBodyTag(code);
84+
}
85+
86+
@Test
87+
public void testRootBodyTagGenerator02() throws Exception {
88+
String code = "def test():\n" + " yield 22\n" + " yield 42\n" + " yield 62\n" + "for i in test():\n" + " i\n";
89+
checkRootTagAndRootBodyTag(code);
90+
}
91+
92+
@Test
93+
public void testRootBodyTagGenerator03() throws Exception {
94+
String code = "def fn(a, b):\n" + " yield a\n" + " yield b\n" + "for i in fn(3,4):\n" + " i\n";
95+
checkRootTagAndRootBodyTag(code);
96+
}
97+
98+
@Test
99+
public void testRootBodyTagFunction01() throws Exception {
100+
String code = "def test():\n" + " return 22\n" + "test()";
101+
checkRootTagAndRootBodyTag(code);
102+
}
103+
104+
@Test
105+
public void testRootBodyTagFunction02() throws Exception {
106+
String code = "def test(a,b):\n" + " return a + b\n" + "test(1, 2)";
107+
HashMap<InstrumentableNode, InstrumentableNode> rootsMap = checkRootTagAndRootBodyTag(code);
108+
InnerRootNode inner = findInnerRootNodeWithEndOffset(rootsMap, 30);
109+
checkBodyPosition(rootsMap, inner, 17, 29);
110+
}
111+
112+
@Test
113+
public void testRootBodyTagFunction03() throws Exception {
114+
String code = "def test(a,b):\n" + " '''This is a simple doc'''\n" + " return a + b\n" + "test(1, 2)";
115+
HashMap<InstrumentableNode, InstrumentableNode> rootsMap = checkRootTagAndRootBodyTag(code);
116+
InnerRootNode inner = findInnerRootNodeWithEndOffset(rootsMap, 59);
117+
checkBodyPosition(rootsMap, inner, 46, 58);
118+
}
119+
120+
@Test
121+
public void testRootBodyTagFunction04() throws Exception {
122+
String code = "def test():\n" + " '''Function without body'''\n" + "test()";
123+
HashMap<InstrumentableNode, InstrumentableNode> rootsMap = checkRootTagAndRootBodyTag(code, true);
124+
InnerRootNode inner = findInnerRootNodeWithEndOffset(rootsMap, 42);
125+
Assert.assertEquals(null, rootsMap.get(inner));
126+
}
127+
128+
@Test
129+
public void testRootBodyTagLambda01() throws Exception {
130+
String code = "x = lambda a, b, c : a + b + c\n" + "x(5, 6, 2)";
131+
checkRootTagAndRootBodyTag(code);
132+
}
133+
134+
@Test
135+
public void testRootBodyTagClass01() throws Exception {
136+
String code = "class MyClass:\n" + " x = 5\n" + "m = MyClass()\n";
137+
HashMap<InstrumentableNode, InstrumentableNode> rootsMap = checkRootTagAndRootBodyTag(code);
138+
InnerRootNode inner = findInnerRootNodeWithEndOffset(rootsMap, 23);
139+
checkBodyPosition(rootsMap, inner, 17, 22);
140+
}
141+
142+
@Test
143+
public void testRootBodyTagClass02() throws Exception {
144+
String code = "class MyClass:\n" + " '''This is a simple test class'''\n" + " x = 5\n" + "m = MyClass()\n";
145+
HashMap<InstrumentableNode, InstrumentableNode> rootsMap = checkRootTagAndRootBodyTag(code);
146+
InnerRootNode inner = findInnerRootNodeWithEndOffset(rootsMap, 59);
147+
checkBodyPosition(rootsMap, inner, 53, 58);
148+
149+
}
150+
151+
private HashMap<InstrumentableNode, InstrumentableNode> checkRootTagAndRootBodyTag(String code) throws Exception {
152+
return checkRootTagAndRootBodyTag(code, false);
153+
}
154+
155+
private HashMap<InstrumentableNode, InstrumentableNode> checkRootTagAndRootBodyTag(String code, boolean possibleEmptyRootTag) throws Exception {
156+
Engine engine = Engine.newBuilder().build();
157+
Context newContext = newContext(engine);
158+
newContext.initialize("python");
159+
Instrument envInstr = newContext.getEngine().getInstruments().get("TestPythonInstrument");
160+
161+
Source source = Source.newBuilder("python", code, "testing").build();
162+
TruffleInstrument.Env env = envInstr.lookup(TestEnvProvider.class).env;
163+
SourceSectionFilter filter = SourceSectionFilter.newBuilder().lineIn(1, source.getLineCount()).tagIs(StandardTags.RootTag.class, StandardTags.RootBodyTag.class).build();
164+
HashMap<InstrumentableNode, InstrumentableNode> rootsMap = new HashMap<>();
165+
env.getInstrumenter().attachExecutionEventListener(filter, new RootTagAndRoodBodyTagListener(rootsMap));
166+
167+
newContext.eval(source);
168+
169+
if (!possibleEmptyRootTag) {
170+
for (InstrumentableNode rootBodyTag : rootsMap.values()) {
171+
assertTrue("There is a RootTag node without RootBodyTag node", rootBodyTag != null);
172+
}
173+
}
174+
return rootsMap;
175+
}
176+
177+
private InnerRootNode findInnerRootNodeWithEndOffset(HashMap<InstrumentableNode, InstrumentableNode> rootsMap, int end) {
178+
for (InstrumentableNode node : rootsMap.keySet()) {
179+
InnerRootNode inner = (InnerRootNode) node;
180+
if (inner.getSourceSection().getCharEndIndex() == end) {
181+
return inner;
182+
}
183+
}
184+
assertTrue("No InnerRootNode found with end offset " + end, false);
185+
return null;
186+
}
187+
188+
private void checkBodyPosition(HashMap<InstrumentableNode, InstrumentableNode> rootsMap, InnerRootNode inner, int start, int end) {
189+
InstrumentableNode body = rootsMap.get(inner);
190+
assertTrue(body != null);
191+
PNode pbody = (PNode) body;
192+
Assert.assertEquals(start, pbody.getSourceSection().getCharIndex());
193+
Assert.assertEquals(end, pbody.getSourceSection().getCharEndIndex());
194+
}
195+
196+
@TruffleInstrument.Registration(id = "TestPythonInstrument", services = TestEnvProvider.class)
197+
public static class TestPythonInstrument extends TruffleInstrument {
198+
199+
@Override
200+
protected void onCreate(final TruffleInstrument.Env env) {
201+
env.registerService(new TestEnvProvider(env));
202+
}
203+
}
204+
205+
private static class TestEnvProvider {
206+
207+
TruffleInstrument.Env env;
208+
209+
TestEnvProvider(TruffleInstrument.Env env) {
210+
this.env = env;
211+
}
212+
}
213+
214+
private static class RootTagAndRoodBodyTagListener implements ExecutionEventListener {
215+
216+
// map of the RootTag -> RootBodyTag
217+
private final HashMap<InstrumentableNode, InstrumentableNode> result;
218+
219+
public RootTagAndRoodBodyTagListener(HashMap<InstrumentableNode, InstrumentableNode> resultMap) {
220+
this.result = resultMap;
221+
}
222+
223+
@Override
224+
public void onEnter(EventContext context, VirtualFrame frame) {
225+
Node node = context.getInstrumentedNode();
226+
InstrumentableNode inode = (InstrumentableNode) node;
227+
228+
if (inode.hasTag(StandardTags.RootTag.class)) {
229+
result.put(inode, null);
230+
}
231+
if (inode.hasTag(StandardTags.RootBodyTag.class)) {
232+
Node parent = node;
233+
while (parent != null) {
234+
if (parent instanceof InstrumentableNode) {
235+
InstrumentableNode iparent = (InstrumentableNode) parent;
236+
if (iparent.hasTag(StandardTags.RootTag.class)) {
237+
assertTrue("RootBodyTag find sooner then RootTag", result.containsKey(iparent));
238+
assertTrue("Found RootTag that already has RootBodyTag", result.get(iparent) == null);
239+
result.put(iparent, inode);
240+
break;
241+
}
242+
if (iparent != inode) {
243+
assertFalse("RootBodyTag is innered in other RootBodyTag", iparent.hasTag(StandardTags.RootBodyTag.class));
244+
}
245+
}
246+
parent = parent.getParent();
247+
}
248+
assertFalse("Found RootBodyTag without RootTag", parent == null);
249+
}
250+
}
251+
252+
@Override
253+
public void onReturnValue(EventContext context, VirtualFrame frame, Object result) {
254+
}
255+
256+
@Override
257+
public void onReturnExceptional(EventContext context, VirtualFrame frame, Throwable exception) {
258+
}
259+
}
260+
}

graalpython/com.oracle.graal.python.test/testData/goldenFiles/AssignmentTests/annotationType02.tast

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,13 @@ ModuleRootNode Name: <module 'annotationType02'> SourceSection: [0,28]`def fn():
3333
ReturnTargetNode SourceSection: [0,28]`def fn():↵ index : ...`
3434
Body: BlockNode SourceSection: None
3535
BlockNode SourceSection: None
36-
WriteLocalVariableNodeGen SourceSection: [12,27]`index : int = 0`
37-
Identifier: index
38-
WriteLocalFrameSlotNodeGen SourceSection: None
39-
Frame: [0,index,Illegal]
40-
IntegerLiteralNode SourceSection: [26,27]`0`
41-
Value: 0
36+
FunctionBodyNode SourceSection: [12,27]`index : int = 0`
37+
WriteLocalVariableNodeGen SourceSection: [12,27]`index : int = 0`
38+
Identifier: index
39+
WriteLocalFrameSlotNodeGen SourceSection: None
40+
Frame: [0,index,Illegal]
41+
IntegerLiteralNode SourceSection: [26,27]`0`
42+
Value: 0
4243
Return Expresssion: ReadLocalVariableNode SourceSection: None
4344
Frame: [1,<return_val>,Illegal]
4445
ReadVariableFromFrameNodeGen SourceSection: None

graalpython/com.oracle.graal.python.test/testData/goldenFiles/AssignmentTests/assignment06.tast

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ ModuleRootNode Name: <module 'assignment06'> SourceSection: [0,29]`def fn():↵
3333
ReturnTargetNode SourceSection: [0,29]`def fn():↵ a = b = ...`
3434
Body: BlockNode SourceSection: None
3535
BlockNode SourceSection: None
36-
BlockNode SourceSection: [12,29]`a = b = c = d = e`
36+
FunctionBodyNode SourceSection: [12,29]`a = b = c = d = e`
3737
WriteLocalVariableNodeGen SourceSection: None
3838
Identifier: <>temp4
3939
WriteLocalFrameSlotNodeGen SourceSection: None

graalpython/com.oracle.graal.python.test/testData/goldenFiles/AssignmentTests/assignment07.tast

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -33,48 +33,49 @@ ModuleRootNode Name: <module 'assignment07'> SourceSection: [0,29]`def fn():↵
3333
ReturnTargetNode SourceSection: [0,29]`def fn():↵ a, b, c ...`
3434
Body: BlockNode SourceSection: None
3535
BlockNode SourceSection: None
36-
DestructuringAssignmentNodeGen SourceSection: [12,29]`a, b, c = 1, 2, 3`
37-
TupleLiteralNode SourceSection: [22,29]`1, 2, 3`
38-
PythonObjectFactoryNodeGen SourceSection: None
39-
IntegerLiteralNode SourceSection: [22,23]`1`
40-
Value: 1
41-
IntegerLiteralNode SourceSection: [25,26]`2`
42-
Value: 2
43-
IntegerLiteralNode SourceSection: [28,29]`3`
44-
Value: 3
45-
WriteLocalVariableNodeGen SourceSection: None
46-
Identifier: <>temp3
47-
WriteLocalFrameSlotNodeGen SourceSection: None
48-
Frame: [3,<>temp3,Illegal]
49-
WriteLocalVariableNodeGen SourceSection: None
50-
Identifier: <>temp4
51-
WriteLocalFrameSlotNodeGen SourceSection: None
52-
Frame: [4,<>temp4,Illegal]
53-
WriteLocalVariableNodeGen SourceSection: None
54-
Identifier: <>temp5
55-
WriteLocalFrameSlotNodeGen SourceSection: None
56-
Frame: [5,<>temp5,Illegal]
57-
WriteLocalVariableNodeGen SourceSection: None
58-
Identifier: a
59-
WriteLocalFrameSlotNodeGen SourceSection: None
60-
Frame: [0,a,Illegal]
61-
ReadLocalVariableNode SourceSection: None
62-
Frame: [3,<>temp3,Illegal]
63-
ReadVariableFromFrameNodeGen SourceSection: None
64-
WriteLocalVariableNodeGen SourceSection: None
65-
Identifier: b
66-
WriteLocalFrameSlotNodeGen SourceSection: None
67-
Frame: [1,b,Illegal]
68-
ReadLocalVariableNode SourceSection: None
69-
Frame: [4,<>temp4,Illegal]
70-
ReadVariableFromFrameNodeGen SourceSection: None
71-
WriteLocalVariableNodeGen SourceSection: None
72-
Identifier: c
73-
WriteLocalFrameSlotNodeGen SourceSection: None
74-
Frame: [2,c,Illegal]
75-
ReadLocalVariableNode SourceSection: None
76-
Frame: [5,<>temp5,Illegal]
77-
ReadVariableFromFrameNodeGen SourceSection: None
36+
FunctionBodyNode SourceSection: [12,29]`a, b, c = 1, 2, 3`
37+
DestructuringAssignmentNodeGen SourceSection: [12,29]`a, b, c = 1, 2, 3`
38+
TupleLiteralNode SourceSection: [22,29]`1, 2, 3`
39+
PythonObjectFactoryNodeGen SourceSection: None
40+
IntegerLiteralNode SourceSection: [22,23]`1`
41+
Value: 1
42+
IntegerLiteralNode SourceSection: [25,26]`2`
43+
Value: 2
44+
IntegerLiteralNode SourceSection: [28,29]`3`
45+
Value: 3
46+
WriteLocalVariableNodeGen SourceSection: None
47+
Identifier: <>temp3
48+
WriteLocalFrameSlotNodeGen SourceSection: None
49+
Frame: [3,<>temp3,Illegal]
50+
WriteLocalVariableNodeGen SourceSection: None
51+
Identifier: <>temp4
52+
WriteLocalFrameSlotNodeGen SourceSection: None
53+
Frame: [4,<>temp4,Illegal]
54+
WriteLocalVariableNodeGen SourceSection: None
55+
Identifier: <>temp5
56+
WriteLocalFrameSlotNodeGen SourceSection: None
57+
Frame: [5,<>temp5,Illegal]
58+
WriteLocalVariableNodeGen SourceSection: None
59+
Identifier: a
60+
WriteLocalFrameSlotNodeGen SourceSection: None
61+
Frame: [0,a,Illegal]
62+
ReadLocalVariableNode SourceSection: None
63+
Frame: [3,<>temp3,Illegal]
64+
ReadVariableFromFrameNodeGen SourceSection: None
65+
WriteLocalVariableNodeGen SourceSection: None
66+
Identifier: b
67+
WriteLocalFrameSlotNodeGen SourceSection: None
68+
Frame: [1,b,Illegal]
69+
ReadLocalVariableNode SourceSection: None
70+
Frame: [4,<>temp4,Illegal]
71+
ReadVariableFromFrameNodeGen SourceSection: None
72+
WriteLocalVariableNodeGen SourceSection: None
73+
Identifier: c
74+
WriteLocalFrameSlotNodeGen SourceSection: None
75+
Frame: [2,c,Illegal]
76+
ReadLocalVariableNode SourceSection: None
77+
Frame: [5,<>temp5,Illegal]
78+
ReadVariableFromFrameNodeGen SourceSection: None
7879
Return Expresssion: ReadLocalVariableNode SourceSection: None
7980
Frame: [6,<return_val>,Illegal]
8081
ReadVariableFromFrameNodeGen SourceSection: None

0 commit comments

Comments
 (0)