comparison graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java @ 9258:07f8d136a05e

Truffle API changes for the Frame API. Introduction of Assumptions class.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 23 Apr 2013 15:34:06 +0200
parents 5e3d1a68664e
children cd1a1d92b3e3
comparison
equal deleted inserted replaced
9257:542712a4732a 9258:07f8d136a05e
32 * <h3>Specializing Frame Slot Types</h3> 32 * <h3>Specializing Frame Slot Types</h3>
33 * 33 *
34 * <p> 34 * <p>
35 * Dynamically typed languages can speculate on the type of a frame slot and only fall back at run 35 * Dynamically typed languages can speculate on the type of a frame slot and only fall back at run
36 * time to a more generic type if necessary. The new type of a frame slot can be set using the 36 * time to a more generic type if necessary. The new type of a frame slot can be set using the
37 * {@link FrameSlot#setType(Class)} method. It is the responsibility of the language implementor to 37 * {@link FrameSlot#setType(Class)} method.
38 * update the content of currently active frames (using {@link Frame#updateToLatestVersion()}).
39 * Also, nodes that depend a specific type of a frame slot must be replaced. Such node can register
40 * a listener that implements {@link FrameSlotTypeListener} using
41 * {@link FrameSlot#registerOneShotTypeListener(FrameSlotTypeListener)}. The event of a type change
42 * on the frame slot will fire only once for the next upcoming change.
43 * </p> 38 * </p>
44 * 39 *
45 * <p> 40 * <p>
46 * The next part of the Truffle API introduction is at 41 * The next part of the Truffle API introduction is at
47 * {@link com.oracle.truffle.api.test.ReturnTypeSpecializationTest}. 42 * {@link com.oracle.truffle.api.test.ReturnTypeSpecializationTest}.
51 46
52 @Test 47 @Test
53 public void test() { 48 public void test() {
54 TruffleRuntime runtime = Truffle.getRuntime(); 49 TruffleRuntime runtime = Truffle.getRuntime();
55 FrameDescriptor frameDescriptor = new FrameDescriptor(); 50 FrameDescriptor frameDescriptor = new FrameDescriptor();
56 FrameSlot slot = frameDescriptor.addFrameSlot("localVar", Integer.class); 51 FrameSlot slot = frameDescriptor.addFrameSlot("localVar", int.class);
57 TestRootNode rootNode = new TestRootNode(new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot)); 52 TestRootNode rootNode = new TestRootNode(new IntAssignLocal(slot, new StringTestChildNode()), new IntReadLocal(slot));
58 CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor); 53 CallTarget target = runtime.createCallTarget(rootNode, frameDescriptor);
59 Assert.assertEquals(Integer.class, slot.getType()); 54 Assert.assertEquals(int.class, slot.getType());
60 Object result = target.call(); 55 Object result = target.call();
61 Assert.assertEquals("42", result); 56 Assert.assertEquals("42", result);
62 Assert.assertEquals(Object.class, slot.getType()); 57 Assert.assertEquals(Object.class, slot.getType());
63 } 58 }
64 59
100 return "42"; 95 return "42";
101 } 96 }
102 97
103 } 98 }
104 99
105 class IntAssignLocal extends FrameSlotNode implements FrameSlotTypeListener { 100 class IntAssignLocal extends FrameSlotNode {
106 101
107 @Child private TestChildNode value; 102 @Child private TestChildNode value;
108 103
109 IntAssignLocal(FrameSlot slot, TestChildNode value) { 104 IntAssignLocal(FrameSlot slot, TestChildNode value) {
110 super(slot); 105 super(slot);
111 this.value = adoptChild(value); 106 this.value = adoptChild(value);
112 slot.registerOneShotTypeListener(this);
113 } 107 }
114 108
115 @Override 109 @Override
116 Object execute(VirtualFrame frame) { 110 Object execute(VirtualFrame frame) {
117 Object o = value.execute(frame); 111 Object o = value.execute(frame);
118 if (o instanceof Integer) { 112 if (o instanceof Integer) {
119 frame.setInt(slot, (Integer) o); 113 try {
120 } else { 114 frame.setInt(slot, (Integer) o);
121 slot.setType(Object.class); 115 } catch (FrameSlotTypeException e) {
122 frame.updateToLatestVersion(); 116 // fall through
123 frame.setObject(slot, o); 117 }
124 } 118 }
119 FrameUtil.setObjectSafe(frame, slot, o);
120 this.replace(new ObjectAssignLocal(slot, value));
125 return null; 121 return null;
126 }
127
128 @Override
129 public void typeChanged(FrameSlot changedSlot, Class<?> oldType) {
130 if (changedSlot.getType() == Object.class) {
131 this.replace(new ObjectAssignLocal(changedSlot, value));
132 }
133 } 122 }
134 } 123 }
135 124
136 class ObjectAssignLocal extends FrameSlotNode { 125 class ObjectAssignLocal extends FrameSlotNode {
137 126
143 } 132 }
144 133
145 @Override 134 @Override
146 Object execute(VirtualFrame frame) { 135 Object execute(VirtualFrame frame) {
147 Object o = value.execute(frame); 136 Object o = value.execute(frame);
148 frame.setObject(slot, o); 137 try {
138 frame.setObject(slot, o);
139 } catch (FrameSlotTypeException e) {
140 FrameUtil.setObjectSafe(frame, slot, o);
141 }
149 return null; 142 return null;
150 } 143 }
151 } 144 }
152 145
153 class IntReadLocal extends FrameSlotNode implements FrameSlotTypeListener { 146 class IntReadLocal extends FrameSlotNode {
154 147
155 IntReadLocal(FrameSlot slot) { 148 IntReadLocal(FrameSlot slot) {
156 super(slot); 149 super(slot);
157 slot.registerOneShotTypeListener(this);
158 } 150 }
159 151
160 @Override 152 @Override
161 Object execute(VirtualFrame frame) { 153 Object execute(VirtualFrame frame) {
162 return frame.getInt(slot); 154 try {
163 } 155 return frame.getInt(slot);
164 156 } catch (FrameSlotTypeException e) {
165 @Override 157 return this.replace(new ObjectReadLocal(slot)).execute(frame);
166 public void typeChanged(FrameSlot changedSlot, Class<?> oldType) {
167 if (changedSlot.getType() == Object.class) {
168 this.replace(new ObjectReadLocal(changedSlot));
169 } 158 }
170 } 159 }
171 } 160 }
172 161
173 class ObjectReadLocal extends FrameSlotNode { 162 class ObjectReadLocal extends FrameSlotNode {
176 super(slot); 165 super(slot);
177 } 166 }
178 167
179 @Override 168 @Override
180 Object execute(VirtualFrame frame) { 169 Object execute(VirtualFrame frame) {
181 return frame.getObject(slot); 170 try {
171 return frame.getObject(slot);
172 } catch (FrameSlotTypeException e) {
173 throw new IllegalStateException(e);
174 }
182 } 175 }
183 } 176 }
184 } 177 }