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