comparison graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/tools/TestNodes.java @ 18988:cca166aa28c0

Truffle/Tools: unit tests for new framework and tool instances
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Tue, 27 Jan 2015 20:27:25 -0800
parents
children 1d6a7ea5de59
comparison
equal deleted inserted replaced
18987:ac114ad31cdd 18988:cca166aa28c0
1 /*
2 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.oracle.truffle.api.test.tools;
24
25 import com.oracle.truffle.api.*;
26 import com.oracle.truffle.api.frame.*;
27 import com.oracle.truffle.api.instrument.*;
28 import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode;
29 import com.oracle.truffle.api.nodes.*;
30 import com.oracle.truffle.api.source.*;
31
32 /**
33 * Nodes and an {@linkplain CallTarget executable ASTs} for testing.
34 */
35 public class TestNodes {
36
37 /**
38 * A fake source used for testing: empty line 1, expression on line 2.
39 */
40 public static final Source expr13Source = Source.fromText("\n6+7\n", "Test Source: expression on line 2 that evaluates to 13");
41 public static final LineLocation expr13Line1 = expr13Source.createLineLocation(1);
42 public static final LineLocation expr13Line2 = expr13Source.createLineLocation(2);
43
44 /**
45 * An executable addition expression that evaluates to 13.
46 */
47 public static CallTarget createExpr13TestCallTarget() {
48 final RootNode rootNode = createExpr13TestRootNode();
49 return Truffle.getRuntime().createCallTarget(rootNode);
50 }
51
52 /**
53 * Root holding an addition expression that evaluates to 13.
54 */
55 public static RootNode createExpr13TestRootNode() {
56 final TestLanguageNode ast = createExpr13AST();
57 final TestRootNode rootNode = new TestRootNode(ast);
58 rootNode.adoptChildren();
59 return rootNode;
60 }
61
62 /**
63 * Addition expression that evaluates to 13, with faked source attribution.
64 */
65 public static TestLanguageNode createExpr13AST() {
66 final SourceSection leftSourceSection = expr13Source.createSection("left", 1, 1);
67 final TestValueNode leftValueNode = new TestValueNode(6, leftSourceSection);
68 final SourceSection rightSourceSection = expr13Source.createSection("right", 3, 1);
69 final TestValueNode rightValueNode = new TestValueNode(7, rightSourceSection);
70 final SourceSection exprSourceSection = expr13Source.createSection("expr", 1, 3);
71 return new TestAddNode(leftValueNode, rightValueNode, exprSourceSection);
72 }
73
74 public abstract static class TestLanguageNode extends Node {
75 public abstract Object execute(VirtualFrame frame);
76
77 public TestLanguageNode() {
78 }
79
80 public TestLanguageNode(SourceSection srcSection) {
81 super(srcSection);
82 }
83
84 @Override
85 public boolean isInstrumentable() {
86 return true;
87 }
88
89 @Override
90 public WrapperNode createWrapperNode() {
91 return new TestWrapperNode(this);
92 }
93 }
94
95 @NodeInfo(cost = NodeCost.NONE)
96 public static class TestWrapperNode extends TestLanguageNode implements WrapperNode {
97 @Child private TestLanguageNode child;
98 @Child private ProbeNode probeNode;
99
100 public TestWrapperNode(TestLanguageNode child) {
101 assert !(child instanceof TestWrapperNode);
102 this.child = child;
103 }
104
105 @Override
106 public String instrumentationInfo() {
107 return "Wrapper node for testing";
108 }
109
110 @Override
111 public boolean isInstrumentable() {
112 return false;
113 }
114
115 @Override
116 public void insertProbe(ProbeNode newProbeNode) {
117 this.probeNode = newProbeNode;
118 }
119
120 @Override
121 public Probe getProbe() {
122 try {
123 return probeNode.getProbe();
124 } catch (IllegalStateException e) {
125 throw new IllegalStateException("Cannot call getProbe() on a wrapper that has no probe");
126 }
127 }
128
129 @Override
130 public Node getChild() {
131 return child;
132 }
133
134 @Override
135 public Object execute(VirtualFrame frame) {
136 probeNode.enter(child, frame);
137 Object result;
138
139 try {
140 result = child.execute(frame);
141 probeNode.returnValue(child, frame, result);
142 } catch (KillException e) {
143 throw (e);
144 } catch (Exception e) {
145 probeNode.returnExceptional(child, frame, e);
146 throw (e);
147 }
148
149 return result;
150 }
151 }
152
153 /**
154 * Truffle requires that all guest languages to have a {@link RootNode} which sits atop any AST
155 * of the guest language. This is necessary since creating a {@link CallTarget} is how Truffle
156 * completes an AST. The root nodes serves as our entry point into a program.
157 */
158 public static class TestRootNode extends RootNode {
159 @Child private TestLanguageNode body;
160
161 /**
162 * This constructor emulates the global machinery that applies registered probers to every
163 * newly created AST. Global registry is not used, since that would interfere with other
164 * tests run in the same environment.
165 */
166 public TestRootNode(TestLanguageNode body) {
167 super(null);
168 this.body = body;
169 }
170
171 @Override
172 public Object execute(VirtualFrame frame) {
173 return body.execute(frame);
174 }
175
176 @Override
177 public boolean isCloningAllowed() {
178 return true;
179 }
180
181 @Override
182 public void applyInstrumentation() {
183 Probe.applyASTProbers(body);
184 }
185 }
186
187 public static class TestValueNode extends TestLanguageNode {
188 private final int value;
189
190 public TestValueNode(int value) {
191 this.value = value;
192 }
193
194 public TestValueNode(int value, SourceSection srcSection) {
195 super(srcSection);
196 this.value = value;
197 }
198
199 @Override
200 public Object execute(VirtualFrame frame) {
201 return new Integer(this.value);
202 }
203 }
204
205 public static class TestAddNode extends TestLanguageNode {
206 @Child private TestLanguageNode leftChild;
207 @Child private TestLanguageNode rightChild;
208
209 public TestAddNode(TestValueNode leftChild, TestValueNode rightChild, SourceSection sourceSection) {
210 super(sourceSection);
211 this.leftChild = insert(leftChild);
212 this.rightChild = insert(rightChild);
213 }
214
215 @Override
216 public Object execute(VirtualFrame frame) {
217 return new Integer(((Integer) leftChild.execute(frame)).intValue() + ((Integer) rightChild.execute(frame)).intValue());
218 }
219 }
220
221 }