1 /* 2 * Copyright (c) 2018, 2025, 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 24 /* 25 * @test id=default 26 * @key randomness 27 * @summary Fuzz tests for jdk.internal.vm.Continuation 28 * @requires vm.continuations 29 * @requires vm.flavor == "server" & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 4) 30 * @requires vm.opt.TieredCompilation == null | vm.opt.TieredCompilation == true 31 * @modules java.base java.base/jdk.internal.vm.annotation java.base/jdk.internal.vm 32 * @library /test/lib 33 * @enablePreview 34 * @build java.base/java.lang.StackWalkerHelper 35 * @build jdk.test.whitebox.WhiteBox 36 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox 37 * 38 * @run main/othervm/timeout=1200 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 39 * Fuzz 40 */ 41 42 /* 43 * @test id=preserve-fp 44 * @key randomness 45 * @summary Fuzz tests for jdk.internal.vm.Continuation 46 * @requires vm.continuations 47 * @requires vm.flavor == "server" & (vm.opt.TieredStopAtLevel == null | vm.opt.TieredStopAtLevel == 4) 48 * @requires vm.opt.TieredCompilation == null | vm.opt.TieredCompilation == true 49 * @modules java.base java.base/jdk.internal.vm.annotation java.base/jdk.internal.vm 50 * @library /test/lib 51 * @enablePreview 52 * @build java.base/java.lang.StackWalkerHelper 53 * @build jdk.test.whitebox.WhiteBox 54 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox 55 * 56 * @run main/othervm/timeout=1200 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. 57 * -XX:+PreserveFramePointer 58 * Fuzz 59 */ 60 61 import jdk.internal.vm.Continuation; 62 import jdk.internal.vm.ContinuationScope; 63 64 import java.lang.invoke.*; 65 import java.lang.reflect.*; 66 import java.lang.StackWalker.StackFrame; 67 import java.nio.file.*; 68 import java.util.*; 69 import java.util.function.*; 70 import java.util.stream.*; 71 import static java.lang.Math.max; 72 import static java.lang.Math.min; 73 import jdk.internal.vm.annotation.DontInline; 74 import jdk.test.lib.Utils; 75 import jdk.test.whitebox.WhiteBox; 76 77 import jdk.test.lib.Platform; 78 import jtreg.SkippedException; 79 80 import com.sun.management.HotSpotDiagnosticMXBean; 81 import java.lang.management.ManagementFactory; 82 83 public class Fuzz implements Runnable { 84 static final boolean VERIFY_STACK = true; // could add significant time 85 static final boolean FILE = true; 86 static final boolean RANDOM = true; 87 static final boolean VERBOSE = false; 88 static final Random RAND = Utils.getRandomInstance(); 89 90 static int COMPILATION_TIMEOUT = (int)(5_000 * Utils.TIMEOUT_FACTOR); // ms 91 92 static final Path TEST_DIR = Path.of(System.getProperty("test.src", ".")); 93 94 public static void main(String[] args) { 95 if (Platform.isSlowDebugBuild() && Platform.isOSX() && Platform.isAArch64()) { 96 throw new SkippedException("Test is unstable with slowdebug bits " 97 + "on macosx-aarch64"); 98 } 99 if (Platform.isPPC()) { 100 COMPILATION_TIMEOUT = COMPILATION_TIMEOUT * 2; 101 } 102 if (Platform.isDebugBuild()) { 103 COMPILATION_TIMEOUT = COMPILATION_TIMEOUT * 2; 104 } 105 warmup(); 106 for (int compileLevel : new int[]{4}) { 107 for (boolean compileRun : new boolean[]{true}) { 108 COMPILE_LEVEL = compileLevel; 109 COMPILE_RUN = compileRun; 110 resetCompilation(); 111 runTests(); 112 } 113 } 114 } 115 116 static void runTests() { 117 if (FILE) testFile("fuzz.dat"); 118 if (RANDOM) testRandom(RAND.nextLong(), 50); 119 } 120 121 //////////////// 122 123 enum Op { 124 CALL_I_INT, CALL_I_DBL, CALL_I_MANY, CALL_I_VAL, 125 CALL_C_INT, CALL_C_DBL, CALL_C_MANY, CALL_C_VAL, 126 CALL_I_CTCH, CALL_C_CTCH, 127 CALL_I_PIN, CALL_C_PIN, 128 MH_I_INT, MH_C_INT, MH_I_MANY, MH_C_MANY, 129 REF_I_INT, REF_C_INT, REF_I_MANY, REF_C_MANY, 130 LOOP, YIELD, THROW, DONE; 131 132 static final EnumSet<Op> BASIC = EnumSet.of(LOOP, YIELD); 133 static final EnumSet<Op> STANDARD = EnumSet.range(CALL_I_INT, CALL_C_CTCH); 134 static final EnumSet<Op> PIN = EnumSet.range(CALL_I_PIN, CALL_C_PIN); 135 static final EnumSet<Op> MH = EnumSet.range(MH_I_INT, MH_C_MANY); 136 static final EnumSet<Op> REFLECTED = EnumSet.range(REF_I_INT, REF_C_MANY); 137 static final EnumSet<Op> NON_CALLS = EnumSet.range(LOOP, DONE); 138 static final EnumSet<Op> COMPILED = EnumSet.copyOf(Arrays.stream(Op.values()).filter(x -> x.toString().contains("_C_")).collect(Collectors.toList())); 139 static final EnumSet<Op> INTERPRETED = EnumSet.copyOf(Arrays.stream(Op.values()).filter(x -> x.toString().contains("_I_")).collect(Collectors.toList())); 140 141 static Op toInterpreted(Op op) { return INTERPRETED.contains(op) ? op : Enum.valueOf(Op.class, op.toString().replace("_C_", "_I_")); } 142 static Op toCompiled(Op op) { return COMPILED.contains(op) ? op : Enum.valueOf(Op.class, op.toString().replace("_I_", "_C_")); } 143 } 144 145 static class Generator { 146 public Op[] generate() { 147 final int length = max(1, pick(5, 10, 50/*, 200*/) + plusOrMinus(5)); 148 149 Set<Op> highProb = new HashSet<Op>(); 150 Set<Op> lowProb = new HashSet<Op>(); 151 152 if (percent(100)) highProb.addAll(Op.BASIC); 153 if (percent(100)) highProb.addAll(Op.STANDARD); 154 if (percent(1)) lowProb.add(Op.THROW); 155 if (percent(3)) lowProb.addAll(Op.PIN); 156 if (percent(3)) lowProb.addAll(Op.MH); 157 if (percent(0)) lowProb.addAll(Op.REFLECTED); 158 if (percent(50)) { 159 highProb.removeAll(Op.INTERPRETED); 160 lowProb.removeAll(Op.INTERPRETED); 161 } 162 Op[] highProb0 = highProb.toArray(Op[]::new); 163 Op[] lowProb0 = lowProb.toArray(Op[]::new); 164 165 int loops = 7; 166 Op[] trace = new Op[length]; 167 for (int i=0; i < trace.length; i++) { 168 trace[i] = pick((lowProb.isEmpty() || percent(90)) ? highProb0 : lowProb0); 169 if (trace[i] == Op.LOOP && (loops--) <= 0) i--; 170 } 171 return trace; 172 } 173 174 private final Random rnd; 175 public Generator(Random rnd) { this.rnd = rnd; } 176 @SafeVarargs 177 private <T> T pick(T... values) { return values[rnd.nextInt(values.length)]; } 178 private boolean percent(int percent) { return rnd.nextInt(100) < percent; } 179 private int plusOrMinus(int n) { return rnd.nextInt(2*n + 1) - n; } 180 } 181 182 static Stream<Op[]> random(Random rnd) { 183 var g = new Generator(rnd); 184 return Stream.iterate(0, x->x+1).map(__ -> g.generate()); 185 } 186 187 static void testRandom(long seed, int number) { 188 System.out.println("-- RANDOM (seed: " + seed + ") --"); 189 testStream(random(new Random(seed)).limit(number)); 190 } 191 192 static void testFile(String fileName) { 193 System.out.println("-- FILE (" + fileName + ") --"); 194 try { 195 testStream(file(TEST_DIR.resolve(fileName))); 196 } catch (java.io.IOException e) { throw new RuntimeException(e); } 197 } 198 199 static Stream<Op[]> file(Path file) throws java.io.IOException { 200 return Files.lines(file).map(String::trim).filter(s -> !s.isBlank() && !s.startsWith("#")).map(Fuzz::parse); 201 } 202 203 static Op[] parse(String line) { 204 return Arrays.stream(line.split(", ")).map(s -> Enum.valueOf(Op.class, s)) 205 .collect(Collectors.toList()).toArray(Op[]::new); 206 } 207 208 static int testCounter; 209 210 static void testStream(Stream<Op[]> traces) { testCounter = 0; traces.forEach(Fuzz::testTrace); } 211 212 //////////////////////////////////////// 213 214 static void testTrace(Op[] trace) { 215 testCounter++; 216 System.out.println("\n" + testCounter + ": COMPILE_LEVEL: " + COMPILE_LEVEL + " COMPILE_RUN: " + COMPILE_RUN); 217 for (int attempt = 0; attempt < 3; attempt++) { 218 if (attempt > 0) System.out.println("RETRYING " + attempt); 219 220 compile(); 221 222 long start = time(); 223 var fuzz = new Fuzz(trace); 224 fuzz.verbose = VERBOSE && attempt == 0; 225 fuzz.print(); 226 int yields = fuzz.test(); 227 time(start, "Test (" + yields + " yields)"); 228 229 if (fuzz.checkCompilation()) 230 break; 231 } 232 } 233 234 static final ContinuationScope SCOPE = new ContinuationScope() {}; 235 236 static class FuzzException extends RuntimeException { 237 public FuzzException(String msg) { super(msg); } 238 } 239 240 boolean verbose = false; 241 242 private final Op[] trace; 243 private int index = -1; 244 private int result = -1; 245 246 private Fuzz(Op[] trace) { this.trace = trace; } 247 248 int test() { 249 Continuation cont = new Continuation(SCOPE, this) { 250 @Override protected void onPinned(Pinned reason) { if (verbose) System.out.println("PINNED " + reason); } 251 }; 252 253 this.yields = 0; 254 int count = 0; 255 try { 256 while (true) { 257 var start = time(); 258 cont.run(); 259 if (cont.isDone()) break; 260 261 assert !shouldThrow(); 262 verifyStack(cont); 263 count++; 264 time(start, "Iteration"); 265 } 266 verifyResult(result); 267 } catch (FuzzException e) { 268 assert shouldThrow(); 269 assert e.getMessage().equals("EX"); 270 assert cont.isDone(); 271 } 272 assert count == yields : "count: " + count + " yields: " + yields; 273 return count; 274 } 275 276 void print() { printTrace(trace); } 277 278 private Op trace(int i) { return i < trace.length ? trace[i] : Op.DONE; } 279 private Op current() { return trace(index); } 280 private Op next(int c) { logOp(c); index++; return current(); } 281 282 ////// Compilation 283 284 private static boolean COMPILE_RUN; 285 private static int COMPILE_LEVEL; 286 287 static final int WARMUP_ITERS = 15_000; 288 static final Op[] WARMUP_TRACE = {Op.MH_C_INT, Op.MH_C_MANY, Op.REF_C_INT, Op.REF_C_MANY, Op.CALL_C_INT, Op.CALL_C_VAL}; 289 290 static void warmup() { 291 final long start = time(); 292 warmup(WARMUP_TRACE, WARMUP_ITERS); // generate (for reflection) and compile method handles 293 time(start, "Warmup"); 294 } 295 296 static void warmup(Op[] trace, int times) { 297 for (int i=0; i<times; i++) { 298 new Fuzz(trace).run(); 299 } 300 } 301 302 static void resetCompilation() { 303 Set<Method> compile = Op.COMPILED.stream().map(Fuzz::method).collect(Collectors.toCollection(HashSet::new)); 304 compile.add(run); 305 306 for (Method m : compile) { 307 WB.deoptimizeMethod(m); 308 WB.clearMethodState(m); 309 } 310 } 311 312 static void enqueueForCompilation(Method m) { 313 if (WB.isMethodCompiled(m)) return; 314 // WB compilation tasks do not expire while others do, 315 // so we wait for an existing task to finish before enqueuing. 316 // Alternatively run with -XX:TieredCompileTaskTimeout=5000 317 Utils.waitForCondition(() -> WB.isMethodQueuedForCompilation(m), 1000); 318 if (WB.isMethodCompiled(m)) return; 319 WB.enqueueMethodForCompilation(m, COMPILE_LEVEL); 320 } 321 322 static void waitForCompilation(Method m) { 323 if (!Utils.waitForCondition(() -> WB.isMethodCompiled(m), COMPILATION_TIMEOUT)) { 324 System.out.println(">>> Compilation status for: " + m); 325 System.out.println("isMethodCompiled: " + WB.isMethodCompiled(m) + " " + 326 "isMethodCompilable: " + WB.isMethodCompilable(m) + " " + 327 "isMethodQueuedForCompilation: " + WB.isMethodQueuedForCompilation(m) + " " + 328 "getMethodCompilationLevel: " + WB.getMethodCompilationLevel(m)); 329 throw new AssertionError("Failed to compile " + m + " in " + COMPILATION_TIMEOUT + "ms"); 330 } 331 } 332 333 static void compileContinuation() { 334 var compile = new HashSet<Method>(); 335 for (Method m : Continuation.class.getDeclaredMethods()) { 336 if (!WB.isMethodCompiled(m)) { 337 if (!Modifier.isNative(m.getModifiers()) 338 && (m.getName().startsWith("enter") 339 || m.getName().startsWith("yield"))) { 340 enqueueForCompilation(m); 341 compile.add(m); 342 } 343 } 344 } 345 346 for (Method m : compile) waitForCompilation(m); 347 } 348 349 static void compile() { 350 final long start = time(); 351 352 compileContinuation(); 353 354 Set<Method> compile = Op.COMPILED.stream().map(Fuzz::method).collect(Collectors.toCollection(HashSet::new)); 355 Set<Method> interpret = Op.INTERPRETED.stream().map(Fuzz::method).collect(Collectors.toCollection(HashSet::new)); 356 (COMPILE_RUN ? compile : interpret).add(run); 357 358 compile.addAll(precompile); 359 360 for (Method m : interpret) WB.makeMethodNotCompilable(m); 361 362 for (Method m : compile) enqueueForCompilation(m); 363 for (Method m : compile) waitForCompilation(m); 364 for (Method m : compile) assert WB.isMethodCompiled(m) : "method: " + m; 365 for (Method m : interpret) assert !WB.isMethodCompiled(m) : "method: " + m; 366 367 time(start, "Compile"); 368 } 369 370 boolean checkContinuationCompilation() { 371 for (Method m : Continuation.class.getDeclaredMethods()) { 372 if (!WB.isMethodCompiled(m)) { 373 if (!Modifier.isNative(m.getModifiers()) 374 && (m.getName().startsWith("enter") 375 || m.getName().startsWith("yield"))) { 376 return false; 377 } 378 } 379 } 380 return true; 381 } 382 383 boolean checkCompilation() { 384 boolean res = true; 385 386 if (!checkContinuationCompilation()) { 387 res = false; 388 System.out.println("CHANGED CONTINUATION COMPILATION"); 389 } 390 391 Op[] newTrace = Arrays.copyOf(trace, trace.length); 392 if (!checkCompilation(newTrace)) { 393 res = false; 394 System.out.println("CHANGED COMPILATION"); 395 printTrace(newTrace); 396 } 397 398 return res; 399 } 400 401 static boolean checkCompilation(Op[] trace) { 402 boolean ok = true; 403 for (int i = 0; i < trace.length; i++) { 404 Op op = trace[i]; 405 if (Op.COMPILED.contains(op) && !WB.isMethodCompiled(method(op))) trace[i] = Op.toInterpreted(op); 406 if (Op.INTERPRETED.contains(op) && WB.isMethodCompiled(method(op))) trace[i] = Op.toCompiled(op); 407 if (op != trace[i]) ok = false; 408 } 409 return ok; 410 } 411 412 /////////// Instance Helpers 413 414 private StackTraceElement[] backtrace; 415 private StackFrame[] fbacktrace; 416 private StackFrame[] lfbacktrace; 417 private int yields; 418 419 void indent(int depth) { 420 // depth = index; 421 for (int i=0; i<depth; i++) System.out.print(" "); 422 } 423 424 void logOp(int iter) { 425 if (!verbose) return; 426 427 int depth = depth(); 428 System.out.print("> " + depth + " "); 429 indent(depth); 430 System.out.println("iter: " + iter + " index: " + index + " op: " + trace(index+1)); 431 } 432 433 <T> T log(T result) { 434 if (!verbose) return result; 435 436 int depth = depth(); 437 System.out.print("> " + depth + " "); 438 indent(depth); 439 System.out.println("result " + result); 440 return result; 441 } 442 443 int depth() { 444 int d = 0; 445 for (int i=0; i<=index && i < trace.length; i++) if (!Op.NON_CALLS.contains(trace[i])) d++; 446 return d; 447 } 448 449 boolean traceHas(Predicate<Op> pred) { 450 for (int i = 0; i < index; i++) if (pred.test(trace[i])) return true; 451 return false; 452 } 453 454 String[] expectedStackTrace() { 455 var ms = new ArrayList<String>(); 456 for (int i = index; i >= 0; i--) if (!Op.NON_CALLS.contains(trace[i])) ms.add(method(trace[i]).getName()); 457 ms.add("run"); 458 return ms.toArray(new String[0]); 459 } 460 461 int computeResult() { 462 // To compute the expected result, we remove all YIELDs from the trace and run it 463 Op[] trace0 = Arrays.stream(trace).filter(op -> op != Op.YIELD) 464 .collect(Collectors.toList()).toArray(Op[]::new); 465 466 Fuzz f0 = new Fuzz(trace0); 467 // if (VERBOSE) { 468 // System.out.println(">>>> RESULT"); 469 // f0.verbose = true; 470 // } 471 f0.run(); 472 return f0.result; 473 } 474 475 void verifyResult(int result) { 476 int computed = computeResult(); 477 assert result == computed : "result: " + result + " expected: " + computed; 478 } 479 480 boolean shouldPin() { 481 // Returns false since we never pin after we removed legacy locking. 482 return traceHas(Op.PIN::contains) && false; 483 } 484 485 void verifyPin(boolean yieldResult) { 486 if (yieldResult) yields++; 487 if (!yieldResult && traceHas(op -> Op.INTERPRETED.contains(op) && Op.REFLECTED.contains(op))) return; 488 assert yieldResult != shouldPin() : "res: " + yieldResult + " shouldPin: " + shouldPin(); 489 } 490 491 boolean shouldThrow() { 492 for (int i = 0; i <= index && i < trace.length; i++) { 493 switch (trace[i]) { 494 case CALL_I_CTCH, CALL_C_CTCH -> { return false; } 495 case THROW -> { return true; } 496 default -> {} 497 } 498 } 499 return false; 500 } 501 502 void captureStack() { 503 // Thread.dumpStack(); 504 if (!VERIFY_STACK) return; 505 backtrace = Thread.currentThread().getStackTrace(); 506 fbacktrace = StackWalkerHelper.getStackFrames(SCOPE); 507 lfbacktrace = StackWalkerHelper.getLiveStackFrames(SCOPE); 508 } 509 510 void verifyStack() { 511 if (!VERIFY_STACK) return; 512 var start = time(); 513 verifyStack(backtrace); 514 verifyStack(backtrace, StackWalkerHelper.toStackTraceElement(fbacktrace)); 515 verifyStack(fbacktrace, lfbacktrace); 516 517 verifyStack(backtrace, Thread.currentThread().getStackTrace()); 518 verifyStack(fbacktrace, StackWalkerHelper.getStackFrames(SCOPE)); 519 verifyStack(lfbacktrace, StackWalkerHelper.getLiveStackFrames(SCOPE)); 520 time(start, "Verify stack"); 521 } 522 523 void verifyStack(Continuation cont) { 524 if (!VERIFY_STACK) return; 525 var start = time(); 526 verifyStack(backtrace); 527 verifyStack(backtrace, StackWalkerHelper.toStackTraceElement(fbacktrace)); 528 verifyStack(fbacktrace, lfbacktrace); 529 530 verifyStack(backtrace, cont.getStackTrace()); 531 verifyStack(fbacktrace, StackWalkerHelper.getStackFrames(cont)); 532 verifyStack(lfbacktrace, StackWalkerHelper.getLiveStackFrames(cont)); 533 time(start, "Verify continuation stack"); 534 } 535 536 static boolean isStackCaptureMechanism(Object sf) { 537 return Fuzz.class.getName().equals(sfClassName(sf)) 538 && ("captureStack".equals(sfMethodName(sf)) || "verifyStack".equals(sfMethodName(sf))); 539 } 540 541 static boolean isPrePostYield(Object sf) { 542 return Fuzz.class.getName().equals(sfClassName(sf)) 543 && ("preYield".equals(sfMethodName(sf)) || "postYield".equals(sfMethodName(sf))); 544 } 545 546 static <T> T[] cutStack(T[] stack) { 547 var list = new ArrayList<T>(); 548 int i = 0; 549 while (i < stack.length && (!Fuzz.class.getName().equals(sfClassName(stack[i])) || isPrePostYield(stack[i]) || isStackCaptureMechanism(stack[i]))) i++; 550 while (i < stack.length && !Continuation.class.getName().equals(sfClassName(stack[i]))) { list.add(stack[i]); i++; } 551 // while (i < stack.length && Continuation.class.getName().equals(sfClassName(stack[i])) && !"enterSpecial".equals(sfMethodName(stack[i]))) { list.add(stack[i]); i++; } 552 return list.toArray(arrayType(stack)); 553 } 554 555 void verifyStack(Object[] observed) { 556 verifyStack( 557 expectedStackTrace(), 558 Arrays.stream(cutStack(observed)).filter(sf -> Fuzz.class.getName().equals(sfClassName(sf))) 559 .collect(Collectors.toList()).toArray(Object[]::new)); 560 } 561 562 static void verifyStack(Object[] expected, Object[] observed) { 563 expected = cutStack(expected); 564 observed = cutStack(observed); 565 boolean equal = true; 566 if (expected.length == observed.length) { 567 for (int i=0; i < expected.length; i++) { 568 if (!sfEquals(expected[i], observed[i])) { 569 // we allow a different line number for the first element 570 if (i > 0 || !Objects.equals(sfClassName(expected[i]), sfClassName(observed[i])) || !Objects.equals(sfMethodName(expected[i]), sfMethodName(observed[i]))) { 571 System.out.println("At index " + i + " expected: " + sfToString(expected[i]) + " observed: " + sfToString(observed[i])); 572 573 equal = false; 574 break; 575 } 576 } 577 } 578 } else { 579 equal = false; 580 System.out.println("Expected length: " + expected.length + " Observed length: " + observed.length); 581 } 582 if (!equal) { 583 System.out.println("Expected: "); for (var sf : expected) System.out.println("\t" + sf); 584 System.out.println("Observed: "); for (var sf : observed) System.out.println("\t" + sf); 585 } 586 assert equal; 587 } 588 589 static String sfClassName(Object f) { 590 return f instanceof String ? Fuzz.class.getName() : 591 (f instanceof StackTraceElement ? ((StackTraceElement)f).getClassName() : ((StackFrame)f).getClassName()); } 592 static String sfMethodName(Object f) { 593 return f instanceof String ? (String)f : 594 (f instanceof StackTraceElement ? ((StackTraceElement)f).getMethodName() : ((StackFrame)f).getMethodName()); } 595 596 static boolean sfEquals(Object a, Object b) { 597 if (a instanceof String) 598 return sfClassName(a).equals(sfClassName(b)) && sfMethodName(a).equals(sfMethodName(b)); 599 600 return a instanceof StackTraceElement ? Objects.equals(a, b) 601 : StackWalkerHelper.equals((StackFrame)a, (StackFrame)b); 602 } 603 604 static String sfToString(Object f) { 605 return f instanceof StackFrame ? StackWalkerHelper.frameToString((StackFrame)f) : Objects.toString(f); 606 } 607 608 //// Value Classes 609 610 static abstract value class BaseValue { 611 public abstract int res(); 612 }; 613 614 static value class SmallValue extends BaseValue { 615 int x1; 616 int x2; 617 618 public SmallValue(int i) { 619 x1 = i; 620 x2 = i; 621 } 622 623 public int res() { 624 return x1 + x2; 625 } 626 }; 627 628 static value class LargeValue extends BaseValue { 629 int x1; 630 int x2; 631 int x3; 632 int x4; 633 int x5; 634 int x6; 635 int x7; 636 637 public LargeValue(int i) { 638 x1 = i; 639 x2 = i; 640 x3 = i; 641 x4 = i; 642 x5 = i; 643 x6 = i; 644 x7 = i; 645 } 646 647 public int res() { 648 return x1 + x2 + x3 + x4 + x5 + x6 + x7; 649 } 650 }; 651 652 static value class OopsValue extends BaseValue { 653 Object x1; 654 Object x2; 655 Object x3; 656 Object x4; 657 Object x5; 658 int x6; 659 660 public OopsValue(int i) { 661 x1 = new Object(); 662 x2 = new Object(); 663 x3 = new Object(); 664 x4 = new Object(); 665 x5 = new Object(); 666 x6 = i; 667 } 668 669 public int res() { 670 return x6; 671 } 672 }; 673 674 public static value class DoubleValue extends BaseValue { 675 double d1; 676 double d2; 677 double d3; 678 double d4; 679 double d5; 680 double d6; 681 double d7; 682 683 public DoubleValue(double d) { 684 d1 = d; 685 d2 = d + 1; 686 d3 = d + 2; 687 d4 = d + 3; 688 d5 = d + 4; 689 d6 = d + 4; 690 d7 = d + 4; 691 } 692 693 public int res() { 694 return (int)(d1 + d2 + d3 + d4 + d5 + d6 + d7); 695 } 696 }; 697 698 static value class MixedValue extends BaseValue { 699 byte x1; 700 short x2; 701 int x3; 702 long x4; 703 double x5; 704 boolean x6; 705 706 public MixedValue(int i) { 707 x1 = (byte)i; 708 x2 = (short)i; 709 x3 = i; 710 x4 = i; 711 x5 = i; 712 x6 = (i % 2) == 0; 713 } 714 715 public int res() { 716 return (int)x1 + (int)x2 + (int)x3 + (int)x4 + (int)x5 + (x6 ? 1 : 0); 717 } 718 }; 719 720 //// Static Helpers 721 722 static void rethrow(Throwable t) { 723 if (t instanceof Error) throw (Error)t; 724 if (t instanceof RuntimeException) throw (RuntimeException)t; 725 throw new AssertionError(t); 726 } 727 728 static <T> T[] arrayType(T[] array) { 729 return (T[])java.lang.reflect.Array.newInstance(array.getClass().componentType(), 0); 730 } 731 732 static void printTrace(Op[] trace) { System.out.println(write(trace)); } 733 734 static String write(Op[] trace) { 735 return Arrays.stream(trace).map(Object::toString).collect(Collectors.joining(", ")); 736 } 737 738 static Method method(Op op) { return method.get(op); } 739 static MethodHandle handle(Op op) { return handle.get(op); } 740 741 static long time() { return System.nanoTime(); } 742 static void time(long startNanos, String message) { 743 final long duration = (System.nanoTime() - startNanos)/1_000_000; 744 if (duration > 500) 745 System.out.println(message + " in " + duration + " ms"); 746 } 747 748 ////// 749 750 private static final WhiteBox WB = WhiteBox.getWhiteBox(); 751 752 static final Class<?>[] run_sig = new Class<?>[]{}; 753 static final Class<?>[] int_sig = new Class<?>[]{int.class, int.class}; 754 static final Class<?>[] dbl_sig = new Class<?>[]{int.class, double.class}; 755 static final Class<?>[] val_sig = new Class<?>[]{int.class, SmallValue.class, 756 LargeValue.class, OopsValue.class, DoubleValue.class, MixedValue.class}; 757 static final Class<?>[] mny_sig = new Class<?>[]{int.class, 758 int.class, double.class, long.class, float.class, Object.class, 759 int.class, double.class, long.class, float.class, Object.class, 760 int.class, double.class, long.class, float.class, Object.class, 761 int.class, double.class, long.class, float.class, Object.class}; 762 static final MethodType run_type = MethodType.methodType(void.class, run_sig); 763 static final MethodType int_type = MethodType.methodType(int.class, int_sig); 764 static final MethodType dbl_type = MethodType.methodType(double.class, dbl_sig); 765 static final MethodType mny_type = MethodType.methodType(int.class, mny_sig); 766 767 static final List<Method> precompile = new ArrayList<>(); 768 769 static final Method run; 770 static final Map<Op, Method> method = new EnumMap<>(Op.class); 771 static final Map<Op, MethodHandle> handle = new EnumMap<>(Op.class); 772 773 static { 774 try { 775 run = Fuzz.class.getDeclaredMethod("run", run_sig); 776 // precompile.add(Fuzz.class.getDeclaredMethod("maybeResetIndex", new Class<?>[]{int.class})); 777 778 method.put(Op.CALL_I_INT, Fuzz.class.getDeclaredMethod("int_int", int_sig)); 779 method.put(Op.CALL_C_INT, Fuzz.class.getDeclaredMethod("com_int", int_sig)); 780 method.put(Op.CALL_I_DBL, Fuzz.class.getDeclaredMethod("int_dbl", dbl_sig)); 781 method.put(Op.CALL_C_DBL, Fuzz.class.getDeclaredMethod("com_dbl", dbl_sig)); 782 method.put(Op.CALL_I_VAL, Fuzz.class.getDeclaredMethod("int_val", val_sig)); 783 method.put(Op.CALL_C_VAL, Fuzz.class.getDeclaredMethod("com_val", val_sig)); 784 method.put(Op.CALL_I_MANY, Fuzz.class.getDeclaredMethod("int_mny", mny_sig)); 785 method.put(Op.CALL_C_MANY, Fuzz.class.getDeclaredMethod("com_mny", mny_sig)); 786 method.put(Op.CALL_I_PIN, Fuzz.class.getDeclaredMethod("int_pin", int_sig)); 787 method.put(Op.CALL_C_PIN, Fuzz.class.getDeclaredMethod("com_pin", int_sig)); 788 789 method.put(Op.CALL_I_CTCH, method(Op.CALL_I_INT)); 790 method.put(Op.CALL_C_CTCH, method(Op.CALL_C_INT)); 791 792 method.put(Op.MH_I_INT, method(Op.CALL_I_INT)); 793 method.put(Op.MH_C_INT, method(Op.CALL_C_INT)); 794 method.put(Op.MH_I_MANY, method(Op.CALL_I_MANY)); 795 method.put(Op.MH_C_MANY, method(Op.CALL_C_MANY)); 796 797 method.put(Op.REF_I_INT, method(Op.CALL_I_INT)); 798 method.put(Op.REF_C_INT, method(Op.CALL_C_INT)); 799 method.put(Op.REF_I_MANY, method(Op.CALL_I_MANY)); 800 method.put(Op.REF_C_MANY, method(Op.CALL_C_MANY)); 801 802 MethodHandles.Lookup lookup = MethodHandles.lookup(); 803 804 handle.put(Op.MH_I_INT, lookup.unreflect(method(Op.CALL_I_INT))); 805 handle.put(Op.MH_C_INT, lookup.unreflect(method(Op.CALL_C_INT))); 806 handle.put(Op.MH_I_MANY, lookup.unreflect(method(Op.CALL_I_MANY))); 807 handle.put(Op.MH_C_MANY, lookup.unreflect(method(Op.CALL_C_MANY))); 808 } catch (ReflectiveOperationException e) { 809 throw new AssertionError(e); 810 } 811 } 812 813 @DontInline void preYield() { captureStack(); } 814 @DontInline void postYield(boolean yieldResult) { verifyPin(yieldResult); verifyStack(); } 815 @DontInline void maybeResetIndex(int index0) { this.index = current() != Op.YIELD ? index0 : index; } 816 @DontInline void throwException() { throw new FuzzException("EX"); } 817 818 @Override 819 public void run() { 820 final int depth = 0; 821 int res = 3; 822 823 int x1 = (int)res, x2 = (int)res, x3 = (int)res, x4 = (int)res; 824 double d1 = (double)res, d2 = (double)res, d3 = (double)res, d4 = (double)res; 825 long l1 = (long)res, l2 = (long)res, l3 = (long)res, l4 = (long)res; 826 float f1 = (float)res, f2 = (float)res, f3 = (float)res, f4 = (float)res; 827 Object o1 = res, o2 = res, o3 = res, o4 = res; 828 SmallValue sv = new SmallValue(res); 829 LargeValue lv = new LargeValue(res); 830 OopsValue ov = new OopsValue(res); 831 DoubleValue dv = new DoubleValue((double)res); 832 MixedValue mv = new MixedValue(res); 833 834 for (int c = 1, index0 = index; c > 0; c--, maybeResetIndex(index0)) { // index0 is the index to which we return when we loop 835 switch (next(c)) { 836 case THROW -> throwException(); 837 case LOOP -> { c += 2; index0 = index; } 838 case YIELD -> { preYield(); boolean y = Continuation.yield(SCOPE); postYield(y); c++; } 839 case DONE -> { break; } 840 case CALL_I_INT -> res += int_int(depth+1, (int)res); 841 case CALL_C_INT -> res += com_int(depth+1, (int)res); 842 case CALL_I_DBL -> res += (int)int_dbl(depth+1, res); 843 case CALL_C_DBL -> res += (int)com_dbl(depth+1, res); 844 case CALL_I_VAL -> res += int_val(depth+1, sv, lv, ov, dv, mv).res(); 845 case CALL_C_VAL -> res += com_val(depth+1, sv, lv, ov, dv, mv).res(); 846 case CALL_I_PIN -> res += int_pin(depth+1, (int)res); 847 case CALL_C_PIN -> res += com_pin(depth+1, (int)res); 848 case CALL_I_MANY -> res += int_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 849 case CALL_C_MANY -> res += com_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 850 case CALL_I_CTCH -> {try { res += int_int(depth+1, (int)res); } catch (FuzzException e) {}} 851 case CALL_C_CTCH -> {try { res += com_int(depth+1, (int)res); } catch (FuzzException e) {}} 852 case MH_I_INT, MH_C_INT -> {try { res += (int)handle(current()).invokeExact(this, depth+1, (int)res); } catch (Throwable e) { rethrow(e); }} 853 case MH_I_MANY, MH_C_MANY -> {try { res += (int)handle(current()).invokeExact(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (Throwable e) { rethrow(e); }} 854 case REF_I_INT, REF_C_INT -> {try { res += (int)method(current()).invoke(this, depth+1, (int)res); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 855 case REF_I_MANY, REF_C_MANY -> {try { res += (int)method(current()).invoke(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 856 default -> throw new AssertionError("Unknown op: " + current()); 857 } 858 } 859 860 this.result = log(res); 861 } 862 863 @DontInline 864 int int_int(final int depth, int x) { 865 int res = x; 866 867 int x1 = (int)res, x2 = (int)res, x3 = (int)res, x4 = (int)res; 868 double d1 = (double)res, d2 = (double)res, d3 = (double)res, d4 = (double)res; 869 long l1 = (long)res, l2 = (long)res, l3 = (long)res, l4 = (long)res; 870 float f1 = (float)res, f2 = (float)res, f3 = (float)res, f4 = (float)res; 871 Object o1 = res, o2 = res, o3 = res, o4 = res; 872 SmallValue sv = new SmallValue(x); 873 LargeValue lv = new LargeValue(x); 874 OopsValue ov = new OopsValue(x); 875 DoubleValue dv = new DoubleValue((double)x); 876 MixedValue mv = new MixedValue(x); 877 878 for (int c = 1, index0 = index; c > 0; c--, maybeResetIndex(index0)) { // index0 is the index to which we return when we loop 879 switch (next(c)) { 880 case THROW -> throwException(); 881 case LOOP -> { c += 2; index0 = index; } 882 case YIELD -> { preYield(); boolean y = Continuation.yield(SCOPE); postYield(y); c++; } 883 case DONE -> { break; } 884 case CALL_I_INT -> res += int_int(depth+1, (int)res); 885 case CALL_C_INT -> res += com_int(depth+1, (int)res); 886 case CALL_I_DBL -> res += (int)int_dbl(depth+1, res); 887 case CALL_C_DBL -> res += (int)com_dbl(depth+1, res); 888 case CALL_I_VAL -> res += int_val(depth+1, sv, lv, ov, dv, mv).res(); 889 case CALL_C_VAL -> res += com_val(depth+1, sv, lv, ov, dv, mv).res(); 890 case CALL_I_PIN -> res += int_pin(depth+1, (int)res); 891 case CALL_C_PIN -> res += com_pin(depth+1, (int)res); 892 case CALL_I_MANY -> res += int_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 893 case CALL_C_MANY -> res += com_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 894 case CALL_I_CTCH -> {try { res += int_int(depth+1, (int)res); } catch (FuzzException e) {}} 895 case CALL_C_CTCH -> {try { res += com_int(depth+1, (int)res); } catch (FuzzException e) {}} 896 case MH_I_INT, MH_C_INT -> {try { res += (int)handle(current()).invokeExact(this, depth+1, (int)res); } catch (Throwable e) { rethrow(e); }} 897 case MH_I_MANY, MH_C_MANY -> {try { res += (int)handle(current()).invokeExact(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (Throwable e) { rethrow(e); }} 898 case REF_I_INT, REF_C_INT -> {try { res += (int)method(current()).invoke(this, depth+1, (int)res); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 899 case REF_I_MANY, REF_C_MANY -> {try { res += (int)method(current()).invoke(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 900 default -> throw new AssertionError("Unknown op: " + current()); 901 } 902 } 903 904 return log(res); 905 } 906 907 @DontInline 908 int com_int(final int depth, int x) { 909 int res = x; 910 911 int x1 = (int)res, x2 = (int)res, x3 = (int)res, x4 = (int)res; 912 double d1 = (double)res, d2 = (double)res, d3 = (double)res, d4 = (double)res; 913 long l1 = (long)res, l2 = (long)res, l3 = (long)res, l4 = (long)res; 914 float f1 = (float)res, f2 = (float)res, f3 = (float)res, f4 = (float)res; 915 Object o1 = res, o2 = res, o3 = res, o4 = res; 916 SmallValue sv = new SmallValue(x); 917 LargeValue lv = new LargeValue(x); 918 OopsValue ov = new OopsValue(x); 919 DoubleValue dv = new DoubleValue((double)x); 920 MixedValue mv = new MixedValue(x); 921 922 for (int c = 1, index0 = index; c > 0; c--, maybeResetIndex(index0)) { // index0 is the index to which we return when we loop 923 switch (next(c)) { 924 case THROW -> throwException(); 925 case LOOP -> { c += 2; index0 = index; } 926 case YIELD -> { preYield(); boolean y = Continuation.yield(SCOPE); postYield(y); c++; } 927 case DONE -> { break; } 928 case CALL_I_INT -> res += int_int(depth+1, (int)res); 929 case CALL_C_INT -> res += com_int(depth+1, (int)res); 930 case CALL_I_DBL -> res += (int)int_dbl(depth+1, res); 931 case CALL_C_DBL -> res += (int)com_dbl(depth+1, res); 932 case CALL_I_VAL -> res += int_val(depth+1, sv, lv, ov, dv, mv).res(); 933 case CALL_C_VAL -> res += com_val(depth+1, sv, lv, ov, dv, mv).res(); 934 case CALL_I_PIN -> res += int_pin(depth+1, (int)res); 935 case CALL_C_PIN -> res += com_pin(depth+1, (int)res); 936 case CALL_I_MANY -> res += int_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 937 case CALL_C_MANY -> res += com_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 938 case CALL_I_CTCH -> {try { res += int_int(depth+1, (int)res); } catch (FuzzException e) {}} 939 case CALL_C_CTCH -> {try { res += com_int(depth+1, (int)res); } catch (FuzzException e) {}} 940 case MH_I_INT, MH_C_INT -> {try { res += (int)handle(current()).invokeExact(this, depth+1, (int)res); } catch (Throwable e) { rethrow(e); }} 941 case MH_I_MANY, MH_C_MANY -> {try { res += (int)handle(current()).invokeExact(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (Throwable e) { rethrow(e); }} 942 case REF_I_INT, REF_C_INT -> {try { res += (int)method(current()).invoke(this, depth+1, (int)res); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 943 case REF_I_MANY, REF_C_MANY -> {try { res += (int)method(current()).invoke(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 944 default -> throw new AssertionError("Unknown op: " + current()); 945 } 946 } 947 948 return log(res); 949 } 950 951 @DontInline 952 double int_dbl(final int depth, double x) { 953 double res = 3.0; 954 955 int x1 = (int)res, x2 = (int)res, x3 = (int)res, x4 = (int)res; 956 double d1 = (double)res, d2 = (double)res, d3 = (double)res, d4 = (double)res; 957 long l1 = (long)res, l2 = (long)res, l3 = (long)res, l4 = (long)res; 958 float f1 = (float)res, f2 = (float)res, f3 = (float)res, f4 = (float)res; 959 Object o1 = res, o2 = res, o3 = res, o4 = res; 960 SmallValue sv = new SmallValue(x1); 961 LargeValue lv = new LargeValue(x1); 962 OopsValue ov = new OopsValue(x1); 963 DoubleValue dv = new DoubleValue((double)x1); 964 MixedValue mv = new MixedValue(x1); 965 966 for (int c = 1, index0 = index; c > 0; c--, maybeResetIndex(index0)) { // index0 is the index to which we return when we loop 967 switch (next(c)) { 968 case THROW -> throwException(); 969 case LOOP -> { c += 2; index0 = index; } 970 case YIELD -> { preYield(); boolean y = Continuation.yield(SCOPE); postYield(y); c++; } 971 case DONE -> { break; } 972 case CALL_I_INT -> res += int_int(depth+1, (int)res); 973 case CALL_C_INT -> res += com_int(depth+1, (int)res); 974 case CALL_I_DBL -> res += (int)int_dbl(depth+1, res); 975 case CALL_C_DBL -> res += (int)com_dbl(depth+1, res); 976 case CALL_I_VAL -> res += int_val(depth+1, sv, lv, ov, dv, mv).res(); 977 case CALL_C_VAL -> res += com_val(depth+1, sv, lv, ov, dv, mv).res(); 978 case CALL_I_PIN -> res += int_pin(depth+1, (int)res); 979 case CALL_C_PIN -> res += com_pin(depth+1, (int)res); 980 case CALL_I_MANY -> res += int_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 981 case CALL_C_MANY -> res += com_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 982 case CALL_I_CTCH -> {try { res += int_int(depth+1, (int)res); } catch (FuzzException e) {}} 983 case CALL_C_CTCH -> {try { res += com_int(depth+1, (int)res); } catch (FuzzException e) {}} 984 case MH_I_INT, MH_C_INT -> {try { res += (int)handle(current()).invokeExact(this, depth+1, (int)res); } catch (Throwable e) { rethrow(e); }} 985 case MH_I_MANY, MH_C_MANY -> {try { res += (int)handle(current()).invokeExact(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (Throwable e) { rethrow(e); }} 986 case REF_I_INT, REF_C_INT -> {try { res += (int)method(current()).invoke(this, depth+1, (int)res); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 987 case REF_I_MANY, REF_C_MANY -> {try { res += (int)method(current()).invoke(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 988 default -> throw new AssertionError("Unknown op: " + current()); 989 } 990 } 991 992 return log(res); 993 } 994 995 @DontInline 996 double com_dbl(final int depth, double x) { 997 double res = 3.0; 998 999 int x1 = (int)res, x2 = (int)res, x3 = (int)res, x4 = (int)res; 1000 double d1 = (double)res, d2 = (double)res, d3 = (double)res, d4 = (double)res; 1001 long l1 = (long)res, l2 = (long)res, l3 = (long)res, l4 = (long)res; 1002 float f1 = (float)res, f2 = (float)res, f3 = (float)res, f4 = (float)res; 1003 Object o1 = res, o2 = res, o3 = res, o4 = res; 1004 SmallValue sv = new SmallValue(x1); 1005 LargeValue lv = new LargeValue(x1); 1006 OopsValue ov = new OopsValue(x1); 1007 DoubleValue dv = new DoubleValue((double)x1); 1008 MixedValue mv = new MixedValue(x1); 1009 1010 for (int c = 1, index0 = index; c > 0; c--, maybeResetIndex(index0)) { // index0 is the index to which we return when we loop 1011 switch (next(c)) { 1012 case THROW -> throwException(); 1013 case LOOP -> { c += 2; index0 = index; } 1014 case YIELD -> { preYield(); boolean y = Continuation.yield(SCOPE); postYield(y); c++; } 1015 case DONE -> { break; } 1016 case CALL_I_INT -> res += int_int(depth+1, (int)res); 1017 case CALL_C_INT -> res += com_int(depth+1, (int)res); 1018 case CALL_I_DBL -> res += (int)int_dbl(depth+1, res); 1019 case CALL_C_DBL -> res += (int)com_dbl(depth+1, res); 1020 case CALL_I_VAL -> res += int_val(depth+1, sv, lv, ov, dv, mv).res(); 1021 case CALL_C_VAL -> res += com_val(depth+1, sv, lv, ov, dv, mv).res(); 1022 case CALL_I_PIN -> res += int_pin(depth+1, (int)res); 1023 case CALL_C_PIN -> res += com_pin(depth+1, (int)res); 1024 case CALL_I_MANY -> res += int_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 1025 case CALL_C_MANY -> res += com_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 1026 case CALL_I_CTCH -> {try { res += int_int(depth+1, (int)res); } catch (FuzzException e) {}} 1027 case CALL_C_CTCH -> {try { res += com_int(depth+1, (int)res); } catch (FuzzException e) {}} 1028 case MH_I_INT, MH_C_INT -> {try { res += (int)handle(current()).invokeExact(this, depth+1, (int)res); } catch (Throwable e) { rethrow(e); }} 1029 case MH_I_MANY, MH_C_MANY -> {try { res += (int)handle(current()).invokeExact(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (Throwable e) { rethrow(e); }} 1030 case REF_I_INT, REF_C_INT -> {try { res += (int)method(current()).invoke(this, depth+1, (int)res); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1031 case REF_I_MANY, REF_C_MANY -> {try { res += (int)method(current()).invoke(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1032 default -> throw new AssertionError("Unknown op: " + current()); 1033 } 1034 } 1035 1036 return log(res); 1037 } 1038 1039 @DontInline 1040 BaseValue int_val(final int depth, SmallValue x1, LargeValue x2, OopsValue x3, DoubleValue x4, MixedValue x5) { 1041 int res = x1.res(); 1042 1043 int x11 = (int)res, x12 = (int)res, x13 = (int)res, x14 = (int)res; 1044 double d1 = (double)res, d2 = (double)res, d3 = (double)res, d4 = (double)res; 1045 long l1 = (long)res, l2 = (long)res, l3 = (long)res, l4 = (long)res; 1046 float f1 = (float)res, f2 = (float)res, f3 = (float)res, f4 = (float)res; 1047 Object o1 = res, o2 = res, o3 = res, o4 = res; 1048 SmallValue sv = new SmallValue(res); 1049 LargeValue lv = new LargeValue(res); 1050 OopsValue ov = new OopsValue(res); 1051 DoubleValue dv = new DoubleValue((double)res); 1052 MixedValue mv = new MixedValue(res); 1053 1054 for (int c = 1, index0 = index; c > 0; c--, maybeResetIndex(index0)) { // index0 is the index to which we return when we loop 1055 switch (next(c)) { 1056 case THROW -> throwException(); 1057 case LOOP -> { c += 2; index0 = index; } 1058 case YIELD -> { preYield(); boolean y = Continuation.yield(SCOPE); postYield(y); c++; } 1059 case DONE -> { break; } 1060 case CALL_I_INT -> res += int_int(depth+1, (int)res); 1061 case CALL_C_INT -> res += com_int(depth+1, (int)res); 1062 case CALL_I_DBL -> res += (int)int_dbl(depth+1, res); 1063 case CALL_C_DBL -> res += (int)com_dbl(depth+1, res); 1064 case CALL_I_VAL -> res += int_val(depth+1, sv, lv, ov, dv, mv).res(); 1065 case CALL_C_VAL -> res += com_val(depth+1, sv, lv, ov, dv, mv).res(); 1066 case CALL_I_PIN -> res += int_pin(depth+1, (int)res); 1067 case CALL_C_PIN -> res += com_pin(depth+1, (int)res); 1068 case CALL_I_MANY -> res += int_mny(depth+1, x11, d1, l1, f1, o1, x12, d2, l2, f2, o2, x13, d3, l3, f3, o3, x14, d4, l4, f4, o4); 1069 case CALL_C_MANY -> res += com_mny(depth+1, x11, d1, l1, f1, o1, x12, d2, l2, f2, o2, x13, d3, l3, f3, o3, x14, d4, l4, f4, o4); 1070 case CALL_I_CTCH -> {try { res += int_int(depth+1, (int)res); } catch (FuzzException e) {}} 1071 case CALL_C_CTCH -> {try { res += com_int(depth+1, (int)res); } catch (FuzzException e) {}} 1072 case MH_I_INT, MH_C_INT -> {try { res += (int)handle(current()).invokeExact(this, depth+1, (int)res); } catch (Throwable e) { rethrow(e); }} 1073 case MH_I_MANY, MH_C_MANY -> {try { res += (int)handle(current()).invokeExact(this, depth+1, x11, d1, l1, f1, o1, x12, d2, l2, f2, o2, x13, d3, l3, f3, o3, x14, d4, l4, f4, o4); } catch (Throwable e) { rethrow(e); }} 1074 case REF_I_INT, REF_C_INT -> {try { res += (int)method(current()).invoke(this, depth+1, (int)res); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1075 case REF_I_MANY, REF_C_MANY -> {try { res += (int)method(current()).invoke(this, depth+1, x11, d1, l1, f1, o1, x12, d2, l2, f2, o2, x13, d3, l3, f3, o3, x14, d4, l4, f4, o4); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1076 default -> throw new AssertionError("Unknown op: " + current()); 1077 } 1078 } 1079 1080 int positiveRes = (res == Integer.MIN_VALUE) ? Integer.MAX_VALUE : Math.abs(res); 1081 switch (positiveRes % 5) { 1082 case 0 -> { return log(new SmallValue(res)); } 1083 case 1 -> { return log(new LargeValue(res)); } 1084 case 2 -> { return log(new OopsValue(res)); } 1085 case 3 -> { return log(new DoubleValue((double)res)); } 1086 case 4 -> { return log(new MixedValue(res)); } 1087 default -> throw new AssertionError("Invalid case"); 1088 } 1089 } 1090 1091 @DontInline 1092 BaseValue com_val(final int depth, SmallValue x1, LargeValue x2, OopsValue x3, DoubleValue x4, MixedValue x5) { 1093 int res = x1.res(); 1094 1095 int x11 = (int)res, x12 = (int)res, x13 = (int)res, x14 = (int)res; 1096 double d1 = (double)res, d2 = (double)res, d3 = (double)res, d4 = (double)res; 1097 long l1 = (long)res, l2 = (long)res, l3 = (long)res, l4 = (long)res; 1098 float f1 = (float)res, f2 = (float)res, f3 = (float)res, f4 = (float)res; 1099 Object o1 = res, o2 = res, o3 = res, o4 = res; 1100 SmallValue sv = new SmallValue(res); 1101 LargeValue lv = new LargeValue(res); 1102 OopsValue ov = new OopsValue(res); 1103 DoubleValue dv = new DoubleValue((double)res); 1104 MixedValue mv = new MixedValue(res); 1105 1106 for (int c = 1, index0 = index; c > 0; c--, maybeResetIndex(index0)) { // index0 is the index to which we return when we loop 1107 switch (next(c)) { 1108 case THROW -> throwException(); 1109 case LOOP -> { c += 2; index0 = index; } 1110 case YIELD -> { preYield(); boolean y = Continuation.yield(SCOPE); postYield(y); c++; } 1111 case DONE -> { break; } 1112 case CALL_I_INT -> res += int_int(depth+1, (int)res); 1113 case CALL_C_INT -> res += com_int(depth+1, (int)res); 1114 case CALL_I_DBL -> res += (int)int_dbl(depth+1, res); 1115 case CALL_C_DBL -> res += (int)com_dbl(depth+1, res); 1116 case CALL_I_VAL -> res += int_val(depth+1, sv, lv, ov, dv, mv).res(); 1117 case CALL_C_VAL -> res += com_val(depth+1, sv, lv, ov, dv, mv).res(); 1118 case CALL_I_PIN -> res += int_pin(depth+1, (int)res); 1119 case CALL_C_PIN -> res += com_pin(depth+1, (int)res); 1120 case CALL_I_MANY -> res += int_mny(depth+1, x11, d1, l1, f1, o1, x12, d2, l2, f2, o2, x13, d3, l3, f3, o3, x14, d4, l4, f4, o4); 1121 case CALL_C_MANY -> res += com_mny(depth+1, x11, d1, l1, f1, o1, x12, d2, l2, f2, o2, x13, d3, l3, f3, o3, x14, d4, l4, f4, o4); 1122 case CALL_I_CTCH -> {try { res += int_int(depth+1, (int)res); } catch (FuzzException e) {}} 1123 case CALL_C_CTCH -> {try { res += com_int(depth+1, (int)res); } catch (FuzzException e) {}} 1124 case MH_I_INT, MH_C_INT -> {try { res += (int)handle(current()).invokeExact(this, depth+1, (int)res); } catch (Throwable e) { rethrow(e); }} 1125 case MH_I_MANY, MH_C_MANY -> {try { res += (int)handle(current()).invokeExact(this, depth+1, x11, d1, l1, f1, o1, x12, d2, l2, f2, o2, x13, d3, l3, f3, o3, x14, d4, l4, f4, o4); } catch (Throwable e) { rethrow(e); }} 1126 case REF_I_INT, REF_C_INT -> {try { res += (int)method(current()).invoke(this, depth+1, (int)res); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1127 case REF_I_MANY, REF_C_MANY -> {try { res += (int)method(current()).invoke(this, depth+1, x11, d1, l1, f1, o1, x12, d2, l2, f2, o2, x13, d3, l3, f3, o3, x14, d4, l4, f4, o4); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1128 default -> throw new AssertionError("Unknown op: " + current()); 1129 } 1130 } 1131 1132 int positiveRes = (res == Integer.MIN_VALUE) ? Integer.MAX_VALUE : Math.abs(res); 1133 switch (positiveRes % 5) { 1134 case 0 -> { return log(new SmallValue(res)); } 1135 case 1 -> { return log(new LargeValue(res)); } 1136 case 2 -> { return log(new OopsValue(res)); } 1137 case 3 -> { return log(new DoubleValue((double)res)); } 1138 case 4 -> { return log(new MixedValue(res)); } 1139 default -> throw new AssertionError("Invalid case"); 1140 } 1141 } 1142 1143 @DontInline 1144 int int_pin(final int depth, int x) { 1145 int res = x; 1146 1147 int x1 = (int)res, x2 = (int)res, x3 = (int)res, x4 = (int)res; 1148 double d1 = (double)res, d2 = (double)res, d3 = (double)res, d4 = (double)res; 1149 long l1 = (long)res, l2 = (long)res, l3 = (long)res, l4 = (long)res; 1150 float f1 = (float)res, f2 = (float)res, f3 = (float)res, f4 = (float)res; 1151 Object o1 = res, o2 = res, o3 = res, o4 = res; 1152 SmallValue sv = new SmallValue(x); 1153 LargeValue lv = new LargeValue(x); 1154 OopsValue ov = new OopsValue(x); 1155 DoubleValue dv = new DoubleValue((double)x); 1156 MixedValue mv = new MixedValue(x); 1157 1158 synchronized (this) { 1159 1160 for (int c = 1, index0 = index; c > 0; c--, maybeResetIndex(index0)) { // index0 is the index to which we return when we loop 1161 switch (next(c)) { 1162 case THROW -> throwException(); 1163 case LOOP -> { c += 2; index0 = index; } 1164 case YIELD -> { preYield(); boolean y = Continuation.yield(SCOPE); postYield(y); c++; } 1165 case DONE -> { break; } 1166 case CALL_I_INT -> res += int_int(depth+1, (int)res); 1167 case CALL_C_INT -> res += com_int(depth+1, (int)res); 1168 case CALL_I_DBL -> res += (int)int_dbl(depth+1, res); 1169 case CALL_C_DBL -> res += (int)com_dbl(depth+1, res); 1170 case CALL_I_VAL -> res += int_val(depth+1, sv, lv, ov, dv, mv).res(); 1171 case CALL_C_VAL -> res += com_val(depth+1, sv, lv, ov, dv, mv).res(); 1172 case CALL_I_PIN -> res += int_pin(depth+1, (int)res); 1173 case CALL_C_PIN -> res += com_pin(depth+1, (int)res); 1174 case CALL_I_MANY -> res += int_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 1175 case CALL_C_MANY -> res += com_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 1176 case CALL_I_CTCH -> {try { res += int_int(depth+1, (int)res); } catch (FuzzException e) {}} 1177 case CALL_C_CTCH -> {try { res += com_int(depth+1, (int)res); } catch (FuzzException e) {}} 1178 case MH_I_INT, MH_C_INT -> {try { res += (int)handle(current()).invokeExact(this, depth+1, (int)res); } catch (Throwable e) { rethrow(e); }} 1179 case MH_I_MANY, MH_C_MANY -> {try { res += (int)handle(current()).invokeExact(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (Throwable e) { rethrow(e); }} 1180 case REF_I_INT, REF_C_INT -> {try { res += (int)method(current()).invoke(this, depth+1, (int)res); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1181 case REF_I_MANY, REF_C_MANY -> {try { res += (int)method(current()).invoke(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1182 default -> throw new AssertionError("Unknown op: " + current()); 1183 } 1184 } 1185 1186 } 1187 1188 return log(res); 1189 } 1190 1191 @DontInline 1192 int com_pin(final int depth, int x) { 1193 int res = x; 1194 1195 int x1 = (int)res, x2 = (int)res, x3 = (int)res, x4 = (int)res; 1196 double d1 = (double)res, d2 = (double)res, d3 = (double)res, d4 = (double)res; 1197 long l1 = (long)res, l2 = (long)res, l3 = (long)res, l4 = (long)res; 1198 float f1 = (float)res, f2 = (float)res, f3 = (float)res, f4 = (float)res; 1199 Object o1 = res, o2 = res, o3 = res, o4 = res; 1200 SmallValue sv = new SmallValue(x); 1201 LargeValue lv = new LargeValue(x); 1202 OopsValue ov = new OopsValue(x); 1203 DoubleValue dv = new DoubleValue((double)x); 1204 MixedValue mv = new MixedValue(x); 1205 1206 synchronized (this) { 1207 1208 for (int c = 1, index0 = index; c > 0; c--, maybeResetIndex(index0)) { // index0 is the index to which we return when we loop 1209 switch (next(c)) { 1210 case THROW -> throwException(); 1211 case LOOP -> { c += 2; index0 = index; } 1212 case YIELD -> { preYield(); boolean y = Continuation.yield(SCOPE); postYield(y); c++; } 1213 case DONE -> { break; } 1214 case CALL_I_INT -> res += int_int(depth+1, (int)res); 1215 case CALL_C_INT -> res += com_int(depth+1, (int)res); 1216 case CALL_I_DBL -> res += (int)int_dbl(depth+1, res); 1217 case CALL_C_DBL -> res += (int)com_dbl(depth+1, res); 1218 case CALL_I_VAL -> res += int_val(depth+1, sv, lv, ov, dv, mv).res(); 1219 case CALL_C_VAL -> res += com_val(depth+1, sv, lv, ov, dv, mv).res(); 1220 case CALL_I_PIN -> res += int_pin(depth+1, (int)res); 1221 case CALL_C_PIN -> res += com_pin(depth+1, (int)res); 1222 case CALL_I_MANY -> res += int_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 1223 case CALL_C_MANY -> res += com_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 1224 case CALL_I_CTCH -> {try { res += int_int(depth+1, (int)res); } catch (FuzzException e) {}} 1225 case CALL_C_CTCH -> {try { res += com_int(depth+1, (int)res); } catch (FuzzException e) {}} 1226 case MH_I_INT, MH_C_INT -> {try { res += (int)handle(current()).invokeExact(this, depth+1, (int)res); } catch (Throwable e) { rethrow(e); }} 1227 case MH_I_MANY, MH_C_MANY -> {try { res += (int)handle(current()).invokeExact(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (Throwable e) { rethrow(e); }} 1228 case REF_I_INT, REF_C_INT -> {try { res += (int)method(current()).invoke(this, depth+1, (int)res); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1229 case REF_I_MANY, REF_C_MANY -> {try { res += (int)method(current()).invoke(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1230 default -> throw new AssertionError("Unknown op: " + current()); 1231 } 1232 } 1233 1234 } 1235 1236 return log(res); 1237 } 1238 1239 @DontInline 1240 int int_mny(int depth, 1241 int x1, double d1, long l1, float f1, Object o1, 1242 int x2, double d2, long l2, float f2, Object o2, 1243 int x3, double d3, long l3, float f3, Object o3, 1244 int x4, double d4, long l4, float f4, Object o4) { 1245 1246 double res = x1 + d2 + f3 + l4 + (double)(o4 instanceof Double ? (Double)o4 : (Integer)o4); 1247 SmallValue sv = new SmallValue(x1); 1248 LargeValue lv = new LargeValue(x1); 1249 OopsValue ov = new OopsValue(x1); 1250 DoubleValue dv = new DoubleValue((double)x1); 1251 MixedValue mv = new MixedValue(x1); 1252 1253 for (int c = 1, index0 = index; c > 0; c--, maybeResetIndex(index0)) { // index0 is the index to which we return when we loop 1254 switch (next(c)) { 1255 case THROW -> throwException(); 1256 case LOOP -> { c += 2; index0 = index; } 1257 case YIELD -> { preYield(); boolean y = Continuation.yield(SCOPE); postYield(y); c++; } 1258 case DONE -> { break; } 1259 case CALL_I_INT -> res += int_int(depth+1, (int)res); 1260 case CALL_C_INT -> res += com_int(depth+1, (int)res); 1261 case CALL_I_DBL -> res += (int)int_dbl(depth+1, res); 1262 case CALL_C_DBL -> res += (int)com_dbl(depth+1, res); 1263 case CALL_I_VAL -> res += int_val(depth+1, sv, lv, ov, dv, mv).res(); 1264 case CALL_C_VAL -> res += com_val(depth+1, sv, lv, ov, dv, mv).res(); 1265 case CALL_I_PIN -> res += int_pin(depth+1, (int)res); 1266 case CALL_C_PIN -> res += com_pin(depth+1, (int)res); 1267 case CALL_I_MANY -> res += int_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 1268 case CALL_C_MANY -> res += com_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 1269 case CALL_I_CTCH -> {try { res += int_int(depth+1, (int)res); } catch (FuzzException e) {}} 1270 case CALL_C_CTCH -> {try { res += com_int(depth+1, (int)res); } catch (FuzzException e) {}} 1271 case MH_I_INT, MH_C_INT -> {try { res += (int)handle(current()).invokeExact(this, depth+1, (int)res); } catch (Throwable e) { rethrow(e); }} 1272 case MH_I_MANY, MH_C_MANY -> {try { res += (int)handle(current()).invokeExact(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (Throwable e) { rethrow(e); }} 1273 case REF_I_INT, REF_C_INT -> {try { res += (int)method(current()).invoke(this, depth+1, (int)res); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1274 case REF_I_MANY, REF_C_MANY -> {try { res += (int)method(current()).invoke(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1275 default -> throw new AssertionError("Unknown op: " + current()); 1276 } 1277 } 1278 1279 return log((int)res); 1280 } 1281 1282 @DontInline 1283 int com_mny(int depth, 1284 int x1, double d1, long l1, float f1, Object o1, 1285 int x2, double d2, long l2, float f2, Object o2, 1286 int x3, double d3, long l3, float f3, Object o3, 1287 int x4, double d4, long l4, float f4, Object o4) { 1288 1289 double res = x1 + d2 + f3 + l4 + (double)(o4 instanceof Double ? (Double)o4 : (Integer)o4); 1290 SmallValue sv = new SmallValue(x1); 1291 LargeValue lv = new LargeValue(x1); 1292 OopsValue ov = new OopsValue(x1); 1293 DoubleValue dv = new DoubleValue((double)x1); 1294 MixedValue mv = new MixedValue(x1); 1295 1296 for (int c = 1, index0 = index; c > 0; c--, maybeResetIndex(index0)) { // index0 is the index to which we return when we loop 1297 switch (next(c)) { 1298 case THROW -> throwException(); 1299 case LOOP -> { c += 2; index0 = index; } 1300 case YIELD -> { preYield(); boolean y = Continuation.yield(SCOPE); postYield(y); c++; } 1301 case DONE -> { break; } 1302 case CALL_I_INT -> res += int_int(depth+1, (int)res); 1303 case CALL_C_INT -> res += com_int(depth+1, (int)res); 1304 case CALL_I_DBL -> res += (int)int_dbl(depth+1, res); 1305 case CALL_C_DBL -> res += (int)com_dbl(depth+1, res); 1306 case CALL_I_VAL -> res += int_val(depth+1, sv, lv, ov, dv, mv).res(); 1307 case CALL_C_VAL -> res += com_val(depth+1, sv, lv, ov, dv, mv).res(); 1308 case CALL_I_PIN -> res += int_pin(depth+1, (int)res); 1309 case CALL_C_PIN -> res += com_pin(depth+1, (int)res); 1310 case CALL_I_MANY -> res += int_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 1311 case CALL_C_MANY -> res += com_mny(depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); 1312 case CALL_I_CTCH -> {try { res += int_int(depth+1, (int)res); } catch (FuzzException e) {}} 1313 case CALL_C_CTCH -> {try { res += com_int(depth+1, (int)res); } catch (FuzzException e) {}} 1314 case MH_I_INT, MH_C_INT -> {try { res += (int)handle(current()).invokeExact(this, depth+1, (int)res); } catch (Throwable e) { rethrow(e); }} 1315 case MH_I_MANY, MH_C_MANY -> {try { res += (int)handle(current()).invokeExact(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (Throwable e) { rethrow(e); }} 1316 case REF_I_INT, REF_C_INT -> {try { res += (int)method(current()).invoke(this, depth+1, (int)res); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1317 case REF_I_MANY, REF_C_MANY -> {try { res += (int)method(current()).invoke(this, depth+1, x1, d1, l1, f1, o1, x2, d2, l2, f2, o2, x3, d3, l3, f3, o3, x4, d4, l4, f4, o4); } catch (InvocationTargetException e) { rethrow(e.getCause()); } catch (IllegalAccessException e) { assert false; }} 1318 default -> throw new AssertionError("Unknown op: " + current()); 1319 } 1320 } 1321 1322 return log((int)res); 1323 } 1324 } --- EOF ---