|
52 | 52 | import com.oracle.truffle.api.TruffleLanguage;
|
53 | 53 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
54 | 54 | import com.oracle.truffle.api.bytecode.BytecodeConfig;
|
| 55 | +import com.oracle.truffle.api.bytecode.BytecodeLocal; |
| 56 | +import com.oracle.truffle.api.bytecode.BytecodeNode; |
55 | 57 | import com.oracle.truffle.api.bytecode.BytecodeParser;
|
56 | 58 | import com.oracle.truffle.api.bytecode.BytecodeRootNode;
|
57 | 59 | import com.oracle.truffle.api.bytecode.ConstantOperand;
|
|
60 | 62 | import com.oracle.truffle.api.bytecode.EpilogReturn;
|
61 | 63 | import com.oracle.truffle.api.bytecode.GenerateBytecode;
|
62 | 64 | import com.oracle.truffle.api.bytecode.Instrumentation;
|
| 65 | +import com.oracle.truffle.api.bytecode.LocalSetter; |
63 | 66 | import com.oracle.truffle.api.bytecode.Operation;
|
64 | 67 | import com.oracle.truffle.api.bytecode.Prolog;
|
65 | 68 | import com.oracle.truffle.api.bytecode.test.ConstantOperandTestRootNode.ReplaceValue;
|
66 | 69 | import com.oracle.truffle.api.bytecode.test.error_tests.ExpectError;
|
67 | 70 | import com.oracle.truffle.api.bytecode.test.error_tests.ExpectWarning;
|
68 | 71 | import com.oracle.truffle.api.dsl.Bind;
|
| 72 | +import com.oracle.truffle.api.dsl.Fallback; |
69 | 73 | import com.oracle.truffle.api.dsl.Specialization;
|
70 | 74 | import com.oracle.truffle.api.exception.AbstractTruffleException;
|
71 | 75 | import com.oracle.truffle.api.frame.FrameDescriptor;
|
@@ -179,6 +183,41 @@ public void testInstrumentationWithConstantAndYield() {
|
179 | 183 | assertEquals(123, cont.getResult());
|
180 | 184 | }
|
181 | 185 |
|
| 186 | + @Test |
| 187 | + public void testConstantWithFallback() { |
| 188 | + ConstantOperandTestRootNode root = parse(b -> { |
| 189 | + b.beginRoot(LANGUAGE); |
| 190 | + b.beginReturn(); |
| 191 | + b.beginCheckValue(42); |
| 192 | + b.emitLoadArgument(0); |
| 193 | + b.endCheckValue(); |
| 194 | + b.endReturn(); |
| 195 | + b.endRoot(); |
| 196 | + }); |
| 197 | + assertEquals(true, root.getCallTarget().call(42)); |
| 198 | + assertEquals(false, root.getCallTarget().call(43)); |
| 199 | + assertEquals(false, root.getCallTarget().call("foo")); |
| 200 | + } |
| 201 | + |
| 202 | + @Test |
| 203 | + public void testLocalSetter() { |
| 204 | + ConstantOperandTestRootNode root = parse(b -> { |
| 205 | + b.beginRoot(LANGUAGE); |
| 206 | + BytecodeLocal local = b.createLocal(); |
| 207 | + b.beginSetCheckValue(42, local); |
| 208 | + b.emitLoadArgument(0); |
| 209 | + b.endSetCheckValue(); |
| 210 | + |
| 211 | + b.beginReturn(); |
| 212 | + b.emitLoadLocal(local); |
| 213 | + b.endReturn(); |
| 214 | + b.endRoot(); |
| 215 | + }); |
| 216 | + assertEquals(true, root.getCallTarget().call(42)); |
| 217 | + assertEquals(false, root.getCallTarget().call(43)); |
| 218 | + assertEquals(false, root.getCallTarget().call("foo")); |
| 219 | + } |
| 220 | + |
182 | 221 | @Test
|
183 | 222 | public void testConstantOperandsInProlog() {
|
184 | 223 | ConstantOperandsInPrologTestRootNode root = ConstantOperandsInPrologTestRootNodeGen.create(BytecodeConfig.DEFAULT, b -> {
|
@@ -276,6 +315,41 @@ public static int doInt(int constantOperand) {
|
276 | 315 | }
|
277 | 316 | }
|
278 | 317 |
|
| 318 | + @Operation |
| 319 | + @ConstantOperand(type = int.class) |
| 320 | + @SuppressWarnings("unused") |
| 321 | + public static final class CheckValue { |
| 322 | + @Specialization(guards = "arg == constantOperand") |
| 323 | + public static boolean doMatch(int constantOperand, int arg) { |
| 324 | + return true; |
| 325 | + } |
| 326 | + |
| 327 | + @Fallback |
| 328 | + public static boolean doNoMatch(int constantOperand, Object arg) { |
| 329 | + return false; |
| 330 | + } |
| 331 | + } |
| 332 | + |
| 333 | + @Operation |
| 334 | + @ConstantOperand(type = int.class) |
| 335 | + @ConstantOperand(type = LocalSetter.class) |
| 336 | + @SuppressWarnings("unused") |
| 337 | + public static final class SetCheckValue { |
| 338 | + @Specialization(guards = "arg == constantOperand") |
| 339 | + public static void doMatch(VirtualFrame frame, int constantOperand, LocalSetter setter, int arg, |
| 340 | + @Bind("$bytecode") BytecodeNode bytecode, |
| 341 | + @Bind("$bci") int bci) { |
| 342 | + setter.setBoolean(bytecode, bci, frame, true); |
| 343 | + } |
| 344 | + |
| 345 | + @Fallback |
| 346 | + public static void doNoMatch(VirtualFrame frame, int constantOperand, LocalSetter setter, Object arg, |
| 347 | + @Bind("$bytecode") BytecodeNode bytecode, |
| 348 | + @Bind("$bci") int bci) { |
| 349 | + setter.setBoolean(bytecode, bci, frame, false); |
| 350 | + } |
| 351 | + } |
| 352 | + |
279 | 353 | @Instrumentation
|
280 | 354 | @ConstantOperand(type = int.class, specifyAtEnd = true)
|
281 | 355 | public static final class ReplaceValue {
|
|
0 commit comments