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