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