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