#!/usr/bin/python3
"""Run various fuzzing operations on random inputs, using wasm-opt.

See "testcase_handlers" below for the list of fuzzing operations.

Usage:

./scripts/fuzz_opt.py

That will run forever or until it finds a problem.

You can put files in the local directory 'fuzz' (under the top level of the
binaryen repo) and the fuzzer will treat them as important content to fuzz
with high frequency.

Setup: Some tools are optional, like emcc and wasm2c. The v8 shell (d8),
however, is used in various sub-fuzzers and so it is mandatory.

Note: For afl-fuzz integration, you probably don't want this, and can use
something like

BINARYEN_CORES=1 BINARYEN_PASS_DEBUG=1 afl-fuzz -i afl-testcases/ -o afl-findings/ -m 100 -d -- bin/wasm-opt -ttf --fuzz-exec --Os @@

(that is on a fixed set of arguments to wasm-opt, though - this
script covers different options being passed)
"""

# ruff: noqa: COM819, ARG002

import contextlib
import difflib
import json
import math
import os
import pathlib
import random
import re
import shutil
import subprocess
import sys
import tarfile
import time
import traceback
from datetime import datetime, timedelta, timezone
from os.path import abspath
from typing import override

from test import fuzzing, shared, support

assert sys.version_info >= (3, 10), 'requires Python 3.10'

# parameters

# feature options that are always passed to the tools.
# XXX fp16 is not yet stable, remove from here when it is
CONSTANT_FEATURE_OPTS = ['--all-features', '--disable-fp16']

INPUT_SIZE_MIN = 1024
INPUT_SIZE_MEAN = 40 * 1024
INPUT_SIZE_MAX = 5 * INPUT_SIZE_MEAN

PRINT_WATS = False

given_seed = None

CLOSED_WORLD_FLAG = '--closed-world'

# V8 does not support shared memories when running with shared-everything
# enabled, so do not fuzz shared-everything for now. The remaining features are
# not yet implemented in v8.
#
# Keep this in sync with bundle_clusterfuzz.py.
DISALLOWED_FEATURES_IN_V8 = [
    'shared-everything',
    'fp16',
    'strings',
    'stack-switching',
    'relaxed-atomics',
    'multibyte',
    'wide-arithmetic',
]


# utilities

def in_binaryen(*args):
    return os.path.join(shared.options.binaryen_root, *args)


def in_bin(tool):
    return os.path.join(shared.options.binaryen_bin, tool)


def random_size():
    if random.random() < 0.25:
        # sometimes do an exponential distribution, which prefers smaller sizes but may
        # also get very high
        ret = int(random.expovariate(1.0 / INPUT_SIZE_MEAN))
        # if the result is valid, use it, otherwise do the normal thing
        # (don't clamp, which would give us a lot of values on the borders)
        if ret >= INPUT_SIZE_MIN and ret <= INPUT_SIZE_MAX:
            return ret

    # most of the time do a simple linear range around the mean
    return random.randint(INPUT_SIZE_MIN, 2 * INPUT_SIZE_MEAN - INPUT_SIZE_MIN)


def make_random_input(input_size, raw_input_data):
    with open(raw_input_data, 'wb') as f:
        f.write(bytes([random.randint(0, 255) for x in range(input_size)]))


def run(cmd, stderr=None, silent=False):
    if not silent:
        print(' '.join(cmd))
    return subprocess.check_output(cmd, stderr=stderr, text=True)


def run_unchecked(cmd):
    print(' '.join(cmd))
    return subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True).stdout


def randomize_pass_debug():
    if random.random() < 0.1:
        print('[pass-debug]')
        os.environ['BINARYEN_PASS_DEBUG'] = '1'
    else:
        os.environ['BINARYEN_PASS_DEBUG'] = '0'
        del os.environ['BINARYEN_PASS_DEBUG']
    print('randomized pass debug:', os.environ.get('BINARYEN_PASS_DEBUG', ''))


@contextlib.contextmanager
def no_pass_debug():
    old_env = os.environ.copy()
    if os.environ.get('BINARYEN_PASS_DEBUG'):
        del os.environ['BINARYEN_PASS_DEBUG']
    try:
        yield
    finally:
        os.environ.update(old_env)


def randomize_feature_opts():
    global FEATURE_OPTS
    FEATURE_OPTS = CONSTANT_FEATURE_OPTS[:]

    if random.random() < 0.1:
        # 10% of the time disable all features, i.e., fuzz the MVP featureset.
        # Fuzzing that is less and less important as more features get enabled
        # by default, but we don't want to lose all coverage for it entirely
        # (and the odds of randomly not selecting any feature, below, is too
        # small - at 17 features it is far less than 1%).
        FEATURE_OPTS += FEATURE_DISABLE_FLAGS
    elif random.random() < 0.333:
        # 1/3 of the remaining 90% pick each feature randomly.
        for possible in FEATURE_DISABLE_FLAGS:
            if random.random() < 0.5:
                FEATURE_OPTS.append(possible)
                if possible in IMPLIED_FEATURE_OPTS:
                    FEATURE_OPTS.extend(IMPLIED_FEATURE_OPTS[possible])
    # Otherwise, use all the features. This is useful to maximize
    # coverage, as enabling more features enables more optimizations and
    # code paths, and also allows all initial contents to run. However,
    # half the time disable the specific ones that are a problem in V8.
    elif random.random() < 0.5:
        # Disable features not allowed in V8 to increase V8 fuzzing.
        FEATURE_OPTS.extend(f'--disable-{feature}' for feature in DISALLOWED_FEATURES_IN_V8)
        # Relaxed SIMD's nondeterminism disables much but not
        # all of our V8 fuzzing, so avoid it.
        FEATURE_OPTS.append('--disable-relaxed-simd')

    print('randomized feature opts:', '\n  ' + '\n  '.join(FEATURE_OPTS))

    # Pick closed or open with equal probability as both matter.
    #
    # Closed world is not a feature flag, technically, since it only makes sense
    # to pass to wasm-opt (and not other tools). But decide on whether we'll
    # be fuzzing in that mode now, as it determinies how we set other things up.
    global CLOSED_WORLD
    CLOSED_WORLD = random.random() < 0.5


ALL_FEATURE_OPTS = ['--all-features', '-all', '--mvp-features', '-mvp']


def update_feature_opts(wasm):
    global FEATURE_OPTS
    # we will re-compute the features; leave all other things as they are
    EXTRA = [x for x in FEATURE_OPTS if not x.startswith('--enable') and
             not x.startswith('--disable') and x not in ALL_FEATURE_OPTS]
    FEATURE_OPTS = run([in_bin('wasm-opt'), wasm] + FEATURE_OPTS + ['--print-features']).strip().split('\n')
    # filter out '', which can happen if no features are enabled
    FEATURE_OPTS = [x for x in FEATURE_OPTS if x]
    print(FEATURE_OPTS, EXTRA)
    FEATURE_OPTS += EXTRA


def randomize_fuzz_settings():
    # a list of the arguments to pass to wasm-opt -ttf when generating the wasm
    global GEN_ARGS
    GEN_ARGS = []

    # a list of the optimizations to run on the wasm
    global FUZZ_OPTS
    FUZZ_OPTS = []

    # a boolean whether NaN values are allowed, or we de-NaN them
    global NANS

    # a boolean whether out of bounds operations are allowed, or we bounds-enforce them
    global OOB

    # a boolean whether we legalize the wasm for JS
    global LEGALIZE

    if random.random() < 0.5:
        NANS = True
    else:
        NANS = False
        GEN_ARGS += ['--denan']
    if random.random() < 0.5:
        OOB = True
    else:
        OOB = False
        GEN_ARGS += ['--no-fuzz-oob']
    if random.random() < 0.5:
        LEGALIZE = True
        GEN_ARGS += ['--legalize-and-prune-js-interface']
    else:
        LEGALIZE = False

    # if GC is enabled then run --dce at the very end, to ensure that our
    # binaries validate in other VMs, due to how non-nullable local validation
    # and unreachable code interact. see
    #   https://github.com/WebAssembly/binaryen/pull/5665
    #   https://github.com/WebAssembly/binaryen/issues/5599
    if '--disable-gc' not in FEATURE_OPTS:
        GEN_ARGS += ['--dce']

        # Add --dce not only when generating the original wasm but to the
        # optimizations we use to create any other wasm file.
        FUZZ_OPTS += ['--dce']

    if CLOSED_WORLD:
        GEN_ARGS += [CLOSED_WORLD_FLAG]
        # Enclose the world much of the time when fuzzing closed-world, so that
        # many types are private and hence optimizable.
        if random.random() < 0.5:
            GEN_ARGS += ['--enclose-world']

    # Test JSPI somewhat rarely, as it may be slower.
    global JSPI
    JSPI = random.random() < 0.25

    print('randomized settings (NaNs, OOB, legalize, JSPI):', NANS, OOB, LEGALIZE, JSPI)


def init_important_initial_contents():
    # Fuzz dir contents are always important to us.
    fuzz_dir = os.path.join(shared.options.binaryen_root, 'fuzz')
    fuzz_cases = shared.get_tests(fuzz_dir, shared.test_suffixes, recursive=True)
    FIXED_IMPORTANT_INITIAL_CONTENTS = fuzz_cases

    # If auto_initial_contents is set we'll also grab all test files that are
    # recent.
    RECENT_DAYS = 30

    # Returns the list of test wast/wat files added or modified within the
    # RECENT_DAYS number of days counting from the commit time of HEAD
    def auto_select_recent_initial_contents():
        # Print 'git log' with changed file status and without commit messages,
        # with commits within RECENT_DAYS number of days, counting from the
        # commit time of HEAD. The reason we use the commit time of HEAD instead
        # of the current system time is to make the results deterministic given
        # the Binaryen HEAD commit.
        head_ts_str = run(['git', 'log', '-1', '--format=%cd', '--date=raw'],
                          silent=True).split()[0]
        head_dt = datetime.utcfromtimestamp(int(head_ts_str))
        start_dt = head_dt - timedelta(days=RECENT_DAYS)
        start_ts = start_dt.replace(tzinfo=timezone.utc).timestamp()
        log = run(['git', 'log', '--name-status', '--format=', '--date=raw', '--no-renames', f'--since={start_ts}'], silent=True).splitlines()
        # Pick up lines in the form of
        # A       test/../something.wast
        # M       test/../something.wast
        # (wat extension is also included)
        p = re.compile(r'^[AM]\stest' + os.sep + r'(.*\.(wat|wast))$')
        matches = [p.match(e) for e in log]
        auto_set = {match.group(1) for match in matches if match}
        auto_set = auto_set.difference(set(FIXED_IMPORTANT_INITIAL_CONTENTS))
        return sorted(auto_set)

    def is_git_repo():
        try:
            ret = run(['git', 'rev-parse', '--is-inside-work-tree'],
                      silent=True, stderr=subprocess.DEVNULL)
            return ret == 'true\n'
        except subprocess.CalledProcessError:
            return False

    if not is_git_repo() and shared.options.auto_initial_contents:
        print('Warning: The current directory is not a git repository, ' +
              'so not automatically selecting initial contents.')
        shared.options.auto_initial_contents = False

    print('- Important provided initial contents:')
    for test in FIXED_IMPORTANT_INITIAL_CONTENTS:
        print('  ' + test)
    print()

    recent_contents = []
    print('- Recently added or modified initial contents ', end='')
    if shared.options.auto_initial_contents:
        print(f'(automatically selected: within last {RECENT_DAYS} days):')
        recent_contents += auto_select_recent_initial_contents()
    for test in recent_contents:
        print('  ' + test)
    print()

    initial_contents = FIXED_IMPORTANT_INITIAL_CONTENTS + recent_contents
    global IMPORTANT_INITIAL_CONTENTS
    IMPORTANT_INITIAL_CONTENTS = [os.path.join(shared.get_test_dir('.'), t) for t in initial_contents]


all_tests = shared.get_all_tests()


def pick_initial_contents():
    # if we use an initial wasm file's contents as the basis for the
    # fuzzing, then that filename, or None if we start entirely from scratch
    global INITIAL_CONTENTS

    INITIAL_CONTENTS = None
    # half the time don't use any initial contents
    if random.random() < 0.5:
        return
    # some of the time use initial contents that are known to be especially
    # important
    if IMPORTANT_INITIAL_CONTENTS and random.random() < 0.5:
        test_name = random.choice(IMPORTANT_INITIAL_CONTENTS)
    else:
        test_name = random.choice(all_tests)
    print('initial contents:', test_name)
    if shared.options.auto_initial_contents:
        # when using auto initial contents, we look through the git history to
        # find test files. if a test file was renamed or removed then it may
        # no longer exist, and we should just skip it.
        if not os.path.exists(test_name):
            return
    if not fuzzing.is_fuzzable(test_name):
        return
    assert os.path.exists(test_name)

    if test_name.endswith('.wast'):
        # this can contain multiple modules, pick one
        split_parts = support.split_wast(test_name)
        if len(split_parts) > 1:
            index = random.randint(0, len(split_parts) - 1)
            chosen = split_parts[index]
            module, _asserts = chosen
            if not module:
                # there is no module in this choice (just asserts), ignore it
                print('initial contents has no module')
                return
            test_name = abspath('initial.wat')
            with open(test_name, 'w') as f:
                f.write(module)
            print(f'  picked submodule {index} from multi-module wast')

    global FEATURE_OPTS
    FEATURE_OPTS += [
        # avoid multivalue for now due to bad interactions with gc non-nullable
        # locals in stacky code. for example, this fails to roundtrip as the
        # tuple code ends up creating stacky binary code that needs to spill
        # non-nullable references to locals, which is not allowed:
        #
        # (module
        #  (type $other (struct))
        #  (func $foo (result (ref $other))
        #   (select
        #    (struct.new $other)
        #    (struct.new $other)
        #    (tuple.extract 2 1
        #     (tuple.make 2
        #      (i32.const 0)
        #      (i32.const 0)
        #     )
        #    )
        #   )
        #  )
        # )
        '--disable-multivalue',
    ]

    # the given wasm may not work with the chosen feature opts. for example, if
    # we pick atomics.wast but want to run with --disable-atomics, then we'd
    # error, so we need to test the wasm. first, make sure it doesn't have a
    # features section, as that would enable a feature that we might want to
    # be disabled, and our test would not error as we want it to.
    if test_name.endswith('.wasm'):
        temp_test_name = 'initial.wasm'
        try:
            run([in_bin('wasm-opt'), test_name, '-all', '--strip-target-features',
                 '-o', temp_test_name])
        except Exception:
            # the input can be invalid if e.g. it is raw data that is used with
            # -ttf as fuzzer input
            print('(initial contents are not valid wasm, ignoring)')
            return
        test_name = temp_test_name

    # Next, test the wasm. Note that we must check for closed world explicitly
    # here, as a testcase may only work in an open world, which means we need to
    # skip it.
    args = FEATURE_OPTS
    if CLOSED_WORLD:
        args.append(CLOSED_WORLD_FLAG)
    try:
        run([in_bin('wasm-opt'), test_name] + args,
            stderr=subprocess.PIPE,
            silent=True)
    except Exception:
        print('(initial contents not valid for features, ignoring)')
        return

    INITIAL_CONTENTS = test_name


# Test outputs we want to ignore are marked this way.
IGNORE = '[binaryen-fuzzer-ignore]'

# Traps are reported as [trap REASON]
TRAP_PREFIX = '[trap '

# Host limits are reported as [host limit REASON]
HOST_LIMIT_PREFIX = '[host limit '

# --fuzz-exec reports calls as [fuzz-exec] export foo
FUZZ_EXEC_EXPORT_PREFIX = '[fuzz-exec] export'

# --fuzz-exec reports a stack limit using this notation
STACK_LIMIT = '[trap stack limit]'

# V8 reports this error in rare cases due to limitations in our handling of non-
# nullable locals in unreachable code, see
#   https://github.com/WebAssembly/binaryen/pull/5665
#   https://github.com/WebAssembly/binaryen/issues/5599
# and also see the --dce workaround below that also links to those issues.
V8_UNINITIALIZED_NONDEF_LOCAL = 'uninitialized non-defaultable local'

# JS exceptions are logged as exception thrown: REASON
EXCEPTION_PREFIX = 'exception thrown: '


# given an export line that includes FUZZ_EXEC_EXPORT_PREFIX, return the export
# that is called
def get_export_from_export_line(export_line):
    assert FUZZ_EXEC_EXPORT_PREFIX in export_line
    return export_line.split(FUZZ_EXEC_EXPORT_PREFIX)[1].strip()


# compare two strings, strictly
def compare(x, y, context, verbose=True):
    if x != y and IGNORE not in {x, y}:
        message = ''.join([a + '\n' for a in difflib.unified_diff(x.splitlines(), y.splitlines(), fromfile='expected', tofile='actual')])
        if verbose:
            raise Exception(f"{context} comparison error, expected to have '{x}' == '{y}', diff:\n\n{message}")
        else:
            raise Exception(f"{context}\nDiff:\n\n{message}")


# converts a possibly-signed integer to an unsigned integer
def unsign(x, bits):
    return x & ((1 << bits) - 1)


# numbers are "close enough" if they just differ in printing, as different
# vms may print at different precision levels and verbosity
def numbers_are_close_enough(x, y):
    # handle nan comparisons like -nan:0x7ffff0 vs NaN, ignoring the bits
    if 'nan' in x.lower() and 'nan' in y.lower():
        return True
    # if one input is a pair, then it is in fact a 64-bit integer that is
    # reported as two 32-bit chunks. convert such 'low high' pairs into a 64-bit
    # integer for comparison to the other value
    if ' ' in x or ' ' in y:
        def to_64_bit(a):
            if ' ' not in a:
                return unsign(int(a), bits=64)
            low, high = a.split(' ')
            return unsign(int(low), 32) + (1 << 32) * unsign(int(high), 32)

        return to_64_bit(x) == to_64_bit(y)
    # float() on the strings will handle many minor differences, like
    # float('1.0') == float('1') , float('inf') == float('Infinity'), etc.
    try:
        return float(x) == float(y)
    except Exception:
        pass
    # otherwise, try a full eval which can handle i64s too
    try:
        ex = eval(x)
        ey = eval(y)
        return ex == ey or float(ex) == float(ey)
    except Exception as e:
        print('failed to check if numbers are close enough:', e)
        return False


FUZZ_EXEC_NOTE_RESULT = '[fuzz-exec] note result'


# compare between vms, which may slightly change how numbers are printed
def compare_between_vms(x, y, context):
    x_lines = x.splitlines()
    y_lines = y.splitlines()
    if len(x_lines) != len(y_lines):
        return compare(x, y, context + ' (note: different number of lines between vms)')

    num_lines = len(x_lines)
    for i in range(num_lines):
        x_line = x_lines[i]
        y_line = y_lines[i]
        if x_line != y_line:
            # this is different, but maybe it's a vm difference we can ignore
            LOGGING_PREFIX = '[LoggingExternalInterface logging'
            if x_line.startswith(LOGGING_PREFIX) and y_line.startswith(LOGGING_PREFIX):
                x_val = x_line[len(LOGGING_PREFIX) + 1:-1]
                y_val = y_line[len(LOGGING_PREFIX) + 1:-1]
                if numbers_are_close_enough(x_val, y_val):
                    continue
            if x_line.startswith(FUZZ_EXEC_NOTE_RESULT) and y_line.startswith(FUZZ_EXEC_NOTE_RESULT):
                x_val = x_line.split(' ')[-1]
                y_val = y_line.split(' ')[-1]
                if numbers_are_close_enough(x_val, y_val):
                    continue

            # this failed to compare. print a custom diff of the relevant lines
            MARGIN = 3
            start = max(i - MARGIN, 0)
            end = min(i + MARGIN, num_lines)
            return compare('\n'.join(x_lines[start:end]), '\n'.join(y_lines[start:end]), context)


def fix_output(out):
    # large doubles may print slightly different on different VMs
    def fix_double(x):
        x = x.group(1)
        if 'nan' in x or 'NaN' in x:
            x = 'nan'
        else:
            x = x.replace('Infinity', 'inf')
            x = str(float(x))
        return 'f64.const ' + x
    out = re.sub(r'f64\.const (-?[nanN:abcdefxIity\d+-.]+)', fix_double, out)

    # mark traps from wasm-opt as exceptions, even though they didn't run in a vm
    out = out.replace(TRAP_PREFIX, EXCEPTION_PREFIX + TRAP_PREFIX)

    # funcref(0) has the index of the function in it, and optimizations can
    # change that index, so ignore it
    out = re.sub(r'funcref\([\d\w$+-_:]+\)', 'funcref()', out)

    # JS prints i31 as just a number, so change "i31ref(N)" (which C++ emits)
    # to "N".
    out = re.sub(r'i31ref\((-?\d+)\)', r'\1', out)

    # Tag names may change due to opts, so canonicalize them.
    out = re.sub(r' tag\$\d+', ' tag', out)

    lines = out.splitlines()
    for i in range(len(lines)):
        line = lines[i]
        if 'Warning: unknown flag' in line or 'Try --help for options' in line:
            # ignore some VM warnings that don't matter, like if a newer V8 has
            # removed a flag that is no longer needed. but print the line so the
            # developer can see it.
            print(line)
            lines[i] = None
        elif EXCEPTION_PREFIX in line:
            # exceptions may differ when optimizing, but an exception should
            # occur, so ignore their types (also js engines print them out
            # slightly differently)
            lines[i] = '     *exception*'
    return '\n'.join([line for line in lines if line is not None])


def fix_spec_output(out):
    out = fix_output(out)
    # spec shows a pointer when it traps, remove that
    out = '\n'.join(ln if 'runtime trap' not in ln else ln[ln.find('runtime trap'):] for ln in out.splitlines())
    # https://github.com/WebAssembly/spec/issues/543 , float consts are messed up
    out = '\n'.join(ln if 'f32' not in ln and 'f64' not in ln else '' for ln in out.splitlines())
    return out


ignored_vm_runs = 0
ignored_vm_run_reasons = {}


# Notes a VM run that we ignore, and the reason for it (for metrics purposes).
# Extra text can also be printed that is not included in the metrics.
def note_ignored_vm_run(reason, extra_text='', amount=1):
    global ignored_vm_runs
    print(f'(ignore VM run: {reason}{extra_text})')
    ignored_vm_runs += amount
    ignored_vm_run_reasons.setdefault(reason, 0)
    ignored_vm_run_reasons[reason] += amount


# Run a VM command, and filter out known issues.
def run_vm(cmd, checked=True):
    def filter_known_issues(output):
        known_issues = [
            # can be caused by flatten, ssa, etc. passes
            'local count too large',
            # can be caused by (array.new $type -1) etc.
            'requested new array is too large',
            # https://github.com/WebAssembly/binaryen/issues/3767
            # note that this text is a little too broad, but the problem is rare
            # enough that it's unlikely to hide an unrelated issue
            'found br_if of type',
            # this text is emitted from V8 when it runs out of memory during a
            # GC allocation.
            'out of memory',
            # if the call stack is exceeded we must ignore this, as
            # optimizations can change whether this happens or not (e.g. by
            # removing locals, which makes stack frames smaller), which is
            # noticeable.
            'Maximum call stack size exceeded',
            # all host limitations are arbitrary and may differ between VMs and
            # also be affected by optimizations, so ignore them.
            # this is the prefix that the binaryen interpreter emits. For V8,
            # there is no single host-limit signal, and we have the earlier
            # strings in this list for known issues (to which more need to be
            # added as necessary).
            HOST_LIMIT_PREFIX,
            # see comment above on this constant
            V8_UNINITIALIZED_NONDEF_LOCAL,
            # V8 does not accept nullable stringviews
            # (https://github.com/WebAssembly/binaryen/pull/6574)
            'expected (ref stringview_wtf16), got nullref',
            'expected type (ref stringview_wtf16), found ref.null of type nullref',
            # wasm64 memories have a V8 limit
            'larger than implementation limit',
        ]
        for issue in known_issues:
            if issue in output:
                note_ignored_vm_run(issue)
                return IGNORE
        return output

    try:
        # some known issues do not cause the entire process to fail
        if checked:
            ret = run(cmd)
        else:
            ret = run_unchecked(cmd)
        return filter_known_issues(ret)
    except subprocess.CalledProcessError:
        # other known issues do make it fail, so re-run without checking for
        # success and see if we should ignore it
        if filter_known_issues(run_unchecked(cmd)) == IGNORE:
            return IGNORE
        raise


MAX_INTERPRETER_ENV_VAR = 'BINARYEN_MAX_INTERPRETER_DEPTH'
MAX_INTERPRETER_DEPTH = 1000


def run_bynterp(wasm, args):
    # increase the interpreter stack depth, to test more things
    os.environ[MAX_INTERPRETER_ENV_VAR] = str(MAX_INTERPRETER_DEPTH)
    try:
        return run_vm([in_bin('wasm-opt'), wasm] + FEATURE_OPTS + args)
    finally:
        del os.environ['BINARYEN_MAX_INTERPRETER_DEPTH']


# Enable even more things than V8_OPTS. V8_OPTS are the flags we want to use
# when testing, on our fixed test suite, but when fuzzing we may want more.
def get_v8_extra_flags():
    # It is important to use the --fuzzing flag because it does things like
    # enable mixed old and new EH (which is an issue since
    # https://github.com/WebAssembly/exception-handling/issues/344 )
    flags = ['--fuzzing']

    # Sometimes add --future, which may enable new JITs and such, which is good
    # to fuzz for V8's sake.
    if random.random() < 0.5:
        flags += ['--future']

    # Sometimes add V8's type assertions.
    if random.random() < 0.5:
        flags += ['--wasm-assert-types']

    # Some other options make sense to use sometimes.
    if random.random() < 0.5:
        flags += ['--no-wasm-generic-wrapper']

    return flags


V8_LIFTOFF_ARGS = ['--liftoff']
V8_NO_LIFTOFF_ARGS = ['--no-liftoff']


# Default to running with liftoff enabled, because we need to pick either
# liftoff or turbo* for consistency (otherwise running the same command twice
# may have different results due to NaN nondeterminism), and liftoff is faster
# for small things.
def run_d8_js(js, args=[], liftoff=True):
    cmd = [shared.V8] + shared.V8_OPTS
    cmd += get_v8_extra_flags()
    if liftoff:
        cmd += V8_LIFTOFF_ARGS
    cmd += [js]
    if args:
        cmd += ['--'] + args
    return run_vm(cmd)


# For JSPI, we must customize fuzz_shell.js. We do so the first time we need
# it, and save the filename here.
JSPI_JS_FILE = None


def get_fuzz_shell_js():
    js = in_binaryen('scripts', 'fuzz_shell.js')

    if not JSPI:
        # Just use the normal fuzz shell script.
        return js

    global JSPI_JS_FILE
    if JSPI_JS_FILE:
        # Use the customized file we've already created.
        return JSPI_JS_FILE

    JSPI_JS_FILE = os.path.abspath('jspi_fuzz_shell.js')
    with open(JSPI_JS_FILE, 'w') as f:
        # Enable JSPI.
        f.write('var JSPI = 1;\n\n')

        # Un-comment the async and await keywords.
        with open(js) as g:
            code = g.read()
        code = code.replace('/* async */', 'async')
        code = code.replace('/* await */', 'await')
        f.write(code)
    return JSPI_JS_FILE


def run_d8_wasm(wasm, liftoff=True, args=[]):
    return run_d8_js(get_fuzz_shell_js(), [wasm] + args, liftoff=liftoff)


def all_disallowed(features):
    return not any(('--enable-' + x) in FEATURE_OPTS for x in features)


class TestCaseHandler:
    # how frequent this handler will be run. 1 means always run it, 0.5 means half the
    # time
    frequency = 1

    def __init__(self):
        self.num_runs = 0

    # If the core handle_pair() method is not overridden, it calls handle() on
    # each of the items. That is useful if you just want the two wasms and don't
    # care about their relationship.
    @override
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        self.handle(before_wasm)
        # Add some visual space between the independent parts.
        print('\n')
        self.handle(after_wasm)

    @override
    def can_run_on_wasm(self, wasm):
        return True

    def increment_runs(self):
        self.num_runs += 1

    def count_runs(self):
        return self.num_runs


# Fuzz the interpreter with --fuzz-exec.
class FuzzExec(TestCaseHandler):
    frequency = 1

    @override
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        run([in_bin('wasm-opt'), before_wasm] + opts + ['--fuzz-exec'])

# VMs


class BinaryenInterpreter:
    name = 'binaryen interpreter'

    @override
    def run(self, wasm):
        output = run_bynterp(wasm, ['--fuzz-exec-before'])
        if output != IGNORE:
            calls = output.count(FUZZ_EXEC_EXPORT_PREFIX)
            errors = output.count(TRAP_PREFIX) + output.count(HOST_LIMIT_PREFIX)
            if errors > calls / 2:
                # A significant amount of execution on this testcase
                # simply trapped, and was not very useful, so mark it
                # as ignored. Ideally the fuzzer testcases would be
                # improved to reduce this number.
                #
                # Note that we don't change output=IGNORE as there may
                # still be useful testing here (up to 50%), so we only
                # note that this is a mostly-ignored run, but we do not
                # ignore the parts that are useful.
                #
                # Note that we set amount to 0.5 because we are run both
                # on the before wasm and the after wasm. Those will be
                # in sync (because the optimizer does not remove traps)
                # and so by setting 0.5 we only increment by 1 for the
                # entire iteration.
                note_ignored_vm_run('too many errors vs calls',
                                    extra_text=f' ({calls} calls, {errors} errors)',
                                    amount=0.5)
        return output

    @override
    def can_run(self, wasm):
        return True

    @override
    def can_compare_to_self(self):
        return True

    @override
    def can_compare_to_other(self, other):
        return True


class D8:
    name = 'd8'

    extra_d8_flags = []

    def run_js(self, js, wasm, checked=True):
        return run_vm([shared.V8, js] + shared.V8_OPTS + get_v8_extra_flags() + self.extra_d8_flags + ['--', wasm], checked=checked)

    @override
    def run(self, wasm):
        return self.run_js(js=get_fuzz_shell_js(), wasm=wasm)

    @override
    def can_run(self, wasm):
        return all_disallowed(DISALLOWED_FEATURES_IN_V8)

    @override
    def can_compare_to_self(self):
        # With nans, VM differences can confuse us, so only very simple VMs
        # can compare to themselves after opts in that case.
        return not NANS

    @override
    def can_compare_to_other(self, other):
        # Relaxed SIMD allows different behavior between VMs, so only
        # allow comparisons to other d8 variants if it is enabled.
        if not all_disallowed(['relaxed-simd']) and not other.name.startswith('d8'):
            return False

        # If not legalized, the JS will fail immediately, so no point to
        # compare to others.
        return self.can_compare_to_self() and LEGALIZE


class D8Liftoff(D8):
    name = 'd8_liftoff'

    extra_d8_flags = V8_LIFTOFF_ARGS


class D8Turboshaft(D8):
    name = 'd8_turboshaft'

    extra_d8_flags = V8_NO_LIFTOFF_ARGS


class Wasm2C:
    name = 'wasm2c'

    def __init__(self):
        # look for wabt in the path. if it's not here, don't run wasm2c
        try:
            wabt_bin = shared.which('wasm2c')
            wabt_root = os.path.dirname(os.path.dirname(wabt_bin))
            self.wasm2c_dir = os.path.join(wabt_root, 'wasm2c')
            if not os.path.isdir(self.wasm2c_dir):
                print('wabt found, but not wasm2c support dir')
                self.wasm2c_dir = None
        except Exception as e:
            print('warning: no wabt found:', e)
            self.wasm2c_dir = None

    @override
    def can_run(self, wasm):
        if self.wasm2c_dir is None:
            return False
        # if we legalize for JS, the ABI is not what C wants
        if LEGALIZE:
            return False
        # relatively slow, so run it less frequently
        if random.random() < 0.5:
            return False
        # wasm2c doesn't support most features
        return all_disallowed(['exception-handling', 'simd', 'threads', 'bulk-memory', 'nontrapping-float-to-int', 'tail-call', 'sign-ext', 'reference-types', 'multivalue', 'gc', 'custom-descriptors', 'relaxed-atomics', 'wide-arithmetic'])

    @override
    def run(self, wasm):
        run([in_bin('wasm-opt'), wasm, '--emit-wasm2c-wrapper=main.c'] + FEATURE_OPTS)
        run(['wasm2c', wasm, '-o', 'wasm.c'])
        compile_cmd = ['clang', 'main.c', 'wasm.c', os.path.join(self.wasm2c_dir, 'wasm-rt-impl.c'), '-I' + self.wasm2c_dir, '-lm', '-Werror']
        run(compile_cmd)
        return run_vm(['./a.out'])

    @override
    def can_compare_to_self(self):
        # The binaryen optimizer changes NaNs in the ways that wasm
        # expects, but that's not quite what C has
        return not NANS

    @override
    def can_compare_to_other(self, other):
        # C won't trap on OOB, and NaNs can differ from wasm VMs
        return not OOB and not NANS


class Wasm2C2Wasm(Wasm2C):
    name = 'wasm2c2wasm'

    def __init__(self):
        super().__init__()

        self.has_emcc = shared.which('emcc') is not None

    @override
    def run(self, wasm):
        run([in_bin('wasm-opt'), wasm, '--emit-wasm2c-wrapper=main.c'] + FEATURE_OPTS)
        run(['wasm2c', wasm, '-o', 'wasm.c'])
        compile_cmd = ['emcc', 'main.c', 'wasm.c',
                       os.path.join(self.wasm2c_dir, 'wasm-rt-impl.c'),
                       '-I' + self.wasm2c_dir,
                       '-lm',
                       '-s', 'ENVIRONMENT=shell',
                       '-s', 'ALLOW_MEMORY_GROWTH']
        # disable the signal handler: emcc looks like unix, but wasm has
        # no signals
        compile_cmd += ['-DWASM_RT_MEMCHECK_SIGNAL_HANDLER=0']
        if random.random() < 0.5:
            compile_cmd += ['-O' + str(random.randint(1, 3))]
        elif random.random() < 0.5:
            if random.random() < 0.5:
                compile_cmd += ['-Os']
            else:
                compile_cmd += ['-Oz']
        # avoid pass-debug on the emcc invocation itself (which runs
        # binaryen to optimize the wasm), as the wasm here can be very
        # large and it isn't what we are focused on testing here
        with no_pass_debug():
            run(compile_cmd)
        return run_d8_js(abspath('a.out.js'))

    @override
    def can_run(self, wasm):
        # quite slow (more steps), so run it less frequently
        if random.random() < 0.8:
            return False
        # prefer not to run if the wasm is very large, as it can OOM
        # the JS engine.
        return super().can_run(wasm) and self.has_emcc and \
            os.path.getsize(wasm) <= INPUT_SIZE_MEAN

    @override
    def can_compare_to_other(self, other):
        # NaNs can differ from wasm VMs
        return not NANS


class CompareVMs(TestCaseHandler):
    frequency = 1

    def __init__(self):
        super().__init__()

        # the binaryen interpreter is specifically useful for various things
        self.bynterpreter = BinaryenInterpreter()

        self.vms = [self.bynterpreter,
                    D8(),
                    D8Liftoff(),
                    D8Turboshaft(),
                    # FIXME: Temprorary disable. See issue #4741 for more details
                    # Wasm2C(),
                    # Wasm2C2Wasm()
                    ]

    @override
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        before = self.run_vms(before_wasm)

        after = self.run_vms(after_wasm)
        self.compare_before_and_after(before, after)

    def run_vms(self, wasm):
        ignored_before = ignored_vm_runs

        # vm_results will map vms to their results
        relevant_vms = []
        vm_results = {}
        for vm in self.vms:
            if vm.can_run(wasm):
                print(f'[CompareVMs] running {vm.name}')
                relevant_vms.append(vm)
                vm_results[vm] = fix_output(vm.run(wasm))

                # If the binaryen interpreter hit a host limitation then do not
                # run other VMs, as that is risky: the host limitation may be an
                # an OOM which could be very costly (lots of swapping, and the
                # OOM may change after opts that remove allocations etc.), or it
                # might be an atomic wait which other VMs implement fully (and
                # the wait might be very long). In general host limitations
                # should be rare (which can be verified by looking at the
                # details of how many things we ended up ignoring), and when we
                # see one we are in a situation that we can't fuzz properly.
                if vm == self.bynterpreter and vm_results[vm] == IGNORE:
                    print('(ignored, so not running other VMs)')

                    # the ignoring should have been noted during run_vms()
                    assert ignored_vm_runs > ignored_before

                    return vm_results

        # compare between the vms on this specific input
        num_vms = len(relevant_vms)
        for i in range(num_vms):
            for j in range(i + 1, num_vms):
                vm1 = relevant_vms[i]
                vm2 = relevant_vms[j]
                if vm1.can_compare_to_other(vm2) and vm2.can_compare_to_other(vm1):
                    compare_between_vms(vm_results[vm1], vm_results[vm2], 'CompareVMs between VMs: ' + vm1.name + ' and ' + vm2.name)

        return vm_results

    @staticmethod
    def compare_before_and_after(before, after):
        # compare each VM to itself on the before and after inputs
        for vm in before.keys():
            if vm in after and vm.can_compare_to_self():
                compare(before[vm], after[vm], 'CompareVMs between before and after: ' + vm.name)


# Check for determinism - the same command must have the same output.
class CheckDeterminism(TestCaseHandler):
    frequency = 0.2

    @override
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        # check for determinism
        run([in_bin('wasm-opt'), before_wasm, '-o', abspath('b1.wasm')] + opts)
        run([in_bin('wasm-opt'), before_wasm, '-o', abspath('b2.wasm')] + opts)
        b1 = open('b1.wasm', 'rb').read()
        b2 = open('b2.wasm', 'rb').read()
        if (b1 != b2):
            run([in_bin('wasm-dis'), abspath('b1.wasm'), '-o', abspath('b1.wat')] + FEATURE_OPTS)
            run([in_bin('wasm-dis'), abspath('b2.wasm'), '-o', abspath('b2.wat')] + FEATURE_OPTS)
            t1 = open(abspath('b1.wat')).read()
            t2 = open(abspath('b2.wat')).read()
            compare(t1, t2, 'Output must be deterministic.', verbose=False)


class Wasm2JS(TestCaseHandler):
    frequency = 0.1

    @override
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        before_wasm_temp = before_wasm + '.temp.wasm'
        after_wasm_temp = after_wasm + '.temp.wasm'
        # legalize the before wasm, so that comparisons to the interpreter
        # later make sense (if we don't do this, the wasm may have i64 exports).
        # after applying other necessary fixes, we'll recreate the after wasm
        # from scratch.
        run([in_bin('wasm-opt'), before_wasm, '--legalize-and-prune-js-interface', '-o', before_wasm_temp] + FEATURE_OPTS)
        compare_before_to_after = random.random() < 0.5
        compare_to_interpreter = compare_before_to_after and random.random() < 0.5
        if compare_before_to_after:
            # to compare the wasm before and after optimizations, we must
            # remove operations that wasm2js does not support with full
            # precision, such as i64-to-f32, as the optimizer can give different
            # results.
            simplification_passes = ['--stub-unsupported-js']
            if compare_to_interpreter:
                # unexpectedly-unaligned loads/stores work fine in wasm in general but
                # not in wasm2js, since typed arrays silently round down, effectively.
                # if we want to compare to the interpreter, remove unaligned
                # operations (by forcing alignment 1, then lowering those into aligned
                # components, which means all loads and stores are of a single byte).
                simplification_passes += ['--dealign', '--alignment-lowering']
            run([in_bin('wasm-opt'), before_wasm_temp, '-o', before_wasm_temp] + simplification_passes + FEATURE_OPTS)
        # now that the before wasm is fixed up, generate a proper after wasm
        run([in_bin('wasm-opt'), before_wasm_temp, '-o', after_wasm_temp] + opts + FEATURE_OPTS)
        # always check for compiler crashes
        before = self.run(before_wasm_temp)
        after = self.run(after_wasm_temp)
        if NANS:
            # with NaNs we can't compare the output, as a reinterpret through
            # memory might end up different in JS than wasm
            return

        def fix_output_for_js(x):
            # start with the normal output fixes that all VMs need
            x = fix_output(x)

            # replace null with 0. the fuzzing harness passes in nulls instead
            # the specific type of a parameter (since null can be cast to
            # anything without issue, and all fuzz_shell.js knows on the JS side
            # is the number of parameters), which can be noticeable in a
            # situation where we optimize and remove casts, like here:
            #
            # function foo(x) { return x | 0; }
            #
            # When optimizing we can remove that | 0, which is valid if the
            # input is valid, but as we said, the fuzz harness passes in a value
            # of the wrong type - which would be cast on use, but if we remove
            # the casts, we end up returning null here and not 0, which the
            # fuzzer can notice.
            x = re.sub(r' null', ' 0', x)

            # wasm2js converts exports to valid JS forms, which affects some of
            # the names in the test suite. Fix those up.
            x = x.replace('log-', 'log_')
            x = x.replace('call-', 'call_')
            x = x.replace('export-', 'export_')

            # check if a number is 0 or a subnormal, which is basically zero
            def is_basically_zero(x):
                # to check if something is a subnormal, compare it to the largest one
                return x >= 0 and x <= 2.22507385850720088902e-308

            def fix_number(x):
                x = x.group(1)
                try:
                    x = float(x)
                    # There appear to be some cases where JS VMs will print
                    # subnormals in full detail while other VMs do not, and vice
                    # versa. Ignore such really tiny numbers.
                    if is_basically_zero(x):
                        x = 0
                except ValueError:
                    # not a floating-point number, nothing to do
                    pass
                return ' => ' + str(x)

            # logging notation is "function_name => result", look for that with
            # a floating-point result that may need to be fixed up
            return re.sub(r' => (-?[\d+-.e\-+]+)', fix_number, x)

        before = fix_output_for_js(before)
        after = fix_output_for_js(after)

        # we must not compare if the wasm hits a trap, as wasm2js does not
        # trap on many things wasm would, and in those cases it can do weird
        # undefined things. in such a case, at least compare up until before
        # the trap, which lets us compare at least some results in some cases.
        # (this is why wasm2js is not in CompareVMs, which does full
        # comparisons - we need to limit the comparison in a special way here)
        interpreter = run_bynterp(before_wasm_temp, ['--fuzz-exec-before'])
        if TRAP_PREFIX in interpreter:
            trap_index = interpreter.index(TRAP_PREFIX)
            # we can't test this function, which the trap is in the middle of.
            # erase everything from this function's output and onward, so we
            # only compare the previous trap-free code
            call_start = interpreter.rindex(FUZZ_EXEC_EXPORT_PREFIX, 0, trap_index)
            call_end = interpreter.index('\n', call_start)
            export_line = interpreter[call_start:call_end]
            # fix up the call line so it matches the JS
            fixed_export_line = fix_output_for_js(export_line)
            before = before[:before.index(fixed_export_line)]
            after = after[:after.index(fixed_export_line)]
            interpreter = interpreter[:interpreter.index(export_line)]

        if compare_before_to_after:
            compare_between_vms(before, after, 'Wasm2JS (before/after)')
            if compare_to_interpreter:
                interpreter = fix_output_for_js(interpreter)
                compare_between_vms(before, interpreter, 'Wasm2JS (vs interpreter)')

    @override
    def run(self, wasm):
        with open(get_fuzz_shell_js()) as f:
            wrapper = f.read()
        cmd = [in_bin('wasm2js'), wasm, '--emscripten']
        # avoid optimizations if we have nans, as we don't handle them with
        # full precision and optimizations can change things
        # OOB accesses are also an issue with optimizations, that can turn the
        # loaded "undefined" into either 0 (with an |0) or stay undefined
        # in optimized code.
        if not NANS and not OOB and random.random() < 0.5:
            # when optimizing also enable deterministic mode, to avoid things
            # like integer divide by zero causing false positives (1 / 0 is
            # Infinity without a  | 0 , and 0 with one, and the truthiness of
            # those differs; we don't want to care about this because it
            # would trap in wasm anyhow)
            cmd += ['-O', '--deterministic']
        main = run(cmd + FEATURE_OPTS)
        with open(os.path.join(shared.options.binaryen_root, 'scripts', 'wasm2js.js')) as f:
            glue = f.read()
        js_file = wasm + '.js'
        with open(js_file, 'w') as f:
            f.write(glue)
            f.write(main)
            f.write(wrapper)
        return run_vm([shared.NODEJS, js_file, abspath('a.wasm')])

    @override
    def can_run_on_wasm(self, wasm):
        # TODO: properly handle memory growth. right now the wasm2js handler
        # uses --emscripten which assumes the Memory is created before, and
        # wasm2js.js just starts with a size of 1 and no limit. We should switch
        # to non-emscripten mode or adding memory information, or check
        # specifically for growth here
        if INITIAL_CONTENTS:
            return False
        # We run in node, which lacks JSPI support, and also we need wasm2js to
        # implement wasm suspending using JS async/await.
        if JSPI:
            return False
        return all_disallowed(['exception-handling', 'simd', 'threads', 'bulk-memory', 'nontrapping-float-to-int', 'tail-call', 'sign-ext', 'reference-types', 'multivalue', 'gc', 'multimemory', 'memory64', 'custom-descriptors', 'relaxed-atomics', 'wide-arithmetic'])


# Returns the wat for a wasm file. If it is already wat, it just returns that
# (useful when reducing with --text, where wasm files are really wat files).
def get_wat(wasm):
    binary = open(wasm, 'rb').read()
    if binary.startswith(b'(module'):
        return binary.decode(encoding='utf-8')
    return run([in_bin('wasm-dis'), wasm] + FEATURE_OPTS)


# given a wasm, find all the exports of particular kinds (for example, kinds
# can be ['func', 'table'] and then we would find exported functions and
# tables).
def get_exports(wasm, kinds):
    wat = get_wat(wasm)
    p = re.compile(r'^ [(]export "(.*[^\\]?)" [(](?:' + '|'.join(kinds) + ')')
    exports = []
    for line in wat.splitlines():
        m = p.match(line)
        if m:
            export = m[1]
            exports.append(export)
    return exports


# given a wasm and a list of exports we want to keep, remove all other exports.
# we also keep a list of default exports, unless that is overridden (overriding
# it may lead to changes in behavior).
def filter_exports(wasm, output, keep, keep_defaults=True):
    # based on
    # https://github.com/WebAssembly/binaryen/wiki/Pruning-unneeded-code-in-wasm-files-with-wasm-metadce#example-pruning-exports

    # we append to keep; avoid modifying the object that was sent in.
    keep = keep[:]

    if keep_defaults:
        # some exports must normally be preserved, if they exist, like the table
        # (which can be called from JS imports for table operations).
        existing_exports = set(get_exports(wasm, ['func', 'table']))
        for export in ['table']:
            if export in existing_exports:
                keep.append(export)

    # build json to represent the exports we want.
    graph = [{
        'name': 'outside',
        'reaches': [f'export-{export}' for export in keep],
        'root': True,
    }]
    for export in keep:
        graph.append({
            'name': f'export-{export}',
            'export': export,
        })

    with open('graph.json', 'w') as f:
        f.write(json.dumps(graph))

    # prune the exports
    run([in_bin('wasm-metadce'), wasm, '-o', output, '--graph-file', 'graph.json'] + FEATURE_OPTS)


# Check if a wasm file would notice normally-unnoticeable changes to exports,
# such as removing one that is not called.
def wasm_notices_export_changes(wasm):
    wat = get_wat(wasm)

    if '(import "fuzzing-support" "call-export' in wat:
        # The call-export* imports are sensitive to the number and identity of
        # exports.
        return True

    if '(import "fuzzing-support" "table-' in wat and '(export "table" (table ' in wat:
        # The table-get/set imports are sensitive to the "table" export.
        return True

    return False


# Fuzz the interpreter with --fuzz-exec -tnh. The tricky thing with traps-never-
# happen mode is that if a trap *does* happen then that is undefined behavior,
# and the optimizer was free to make changes to observable behavior there. The
# fuzzer therefore needs to ignore code that traps.
class TrapsNeverHappen(TestCaseHandler):
    frequency = 0.25

    @override
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        before = run_bynterp(before_wasm, ['--fuzz-exec-before'])

        if before == IGNORE:
            # There is no point to continue since we can't compare this output
            # to anything, and there is a risk since if we did so we might run
            # into an infinite loop (see below).
            return

        # if a trap happened, we must stop comparing from that.
        if TRAP_PREFIX in before:
            trap_index = before.index(TRAP_PREFIX)
            # we can't test this function, which the trap is in the middle of
            # (tnh could move the trap around, so even things before the trap
            # are unsafe). we can only safely call exports before this one, so
            # remove those from the binary.
            #
            # first, find the function call during which the trap happened, by
            # finding the call line right before us. that is, the output looks
            # like this:
            #
            #   [fuzz-exec] export foo
            #   .. stuff happening during foo ..
            #   [fuzz-exec] export bar
            #   .. stuff happening during bar ..
            #
            # if the trap happened during bar, the relevant call line is
            # "[fuzz-exec] export bar".
            call_start = before.rfind(FUZZ_EXEC_EXPORT_PREFIX, 0, trap_index)
            if call_start < 0:
                # the trap happened before we called an export, so it occured
                # during startup (the start function, or memory segment
                # operations, etc.). in that case there is nothing for us to
                # compare here; just leave.
                return
            # include the line separator in the index, as function names may
            # be prefixes of each other
            call_end = before.index(os.linesep, call_start) + 1
            # we now know the contents of the call line after which the trap
            # happens, which is something like "[fuzz-exec] export bar", and
            # it is unique since it contains the function being called.
            export_line = before[call_start:call_end]
            trapping_export = get_export_from_export_line(export_line)

            # now that we know the trapping export, we can leave only the safe
            # ones that are before it
            safe_exports = []
            for line in before.splitlines():
                if FUZZ_EXEC_EXPORT_PREFIX in line:
                    export = get_export_from_export_line(line)
                    if export == trapping_export:
                        break
                    safe_exports.append(export)

            # filter out the other exports
            filtered = before_wasm + '.filtered.wasm'
            filter_exports(before_wasm, filtered, safe_exports)
            before_wasm = filtered

            # re-execute the now safe wasm
            before = run_bynterp(before_wasm, ['--fuzz-exec-before'])
            assert TRAP_PREFIX not in before, 'we should have fixed this problem'

        after_wasm_tnh = after_wasm + '.tnh.wasm'
        run([in_bin('wasm-opt'), before_wasm, '-o', after_wasm_tnh, '-tnh'] + opts + FEATURE_OPTS)
        after = run_bynterp(after_wasm_tnh, ['--fuzz-exec-before'])

        # some results cannot be compared, so we must filter them out here.
        def ignore_references(out):
            ret = []
            for line in out.splitlines():
                # only result lines are relevant here, which look like
                # [fuzz-exec] note result: foo => [...]
                if FUZZ_EXEC_NOTE_RESULT in line:
                    # we want to filter out things like "anyref(null)" or
                    # "[ref null data]".
                    if 'ref(' in line or 'ref ' in line:
                        line = line[:line.index('=>') + 2] + ' ?'
                ret.append(line)
            return '\n'.join(ret)

        before = fix_output(ignore_references(before))
        after = fix_output(ignore_references(after))

        compare_between_vms(before, after, 'TrapsNeverHappen')

    @override
    def can_run_on_wasm(self, wasm):
        # If the wasm is sensitive to changes in exports then we cannot alter
        # them, but we must remove trapping exports (see above), so we cannot
        # run in such a case.
        return not wasm_notices_export_changes(wasm)


# Tests wasm-ctor-eval
class CtorEval(TestCaseHandler):
    frequency = 0.1

    @override
    def handle(self, wasm):
        # Get the list of func exports, so we can tell ctor-eval what to eval.
        func_exports = get_exports(wasm, ['func'])
        # Avoid names that need escaping. Just allow simple names like func_256,
        # which the fuzzer emits
        # TODO: fix escaping in the tool and here
        func_exports = [export for export in func_exports if re.fullmatch(r'^[0-9a-zA-Z_]+$', export)]
        ctors = ','.join(func_exports)
        if not ctors:
            return

        # The fuzzer evaluates exports in the order they are given, so if there
        # are global exports it may read them before the ctors are run - but
        # the ctors are meant to run before anything else, and can modify
        # those global values. Keep only function exports to avoid this
        # confusion.
        filtered = wasm + '.filtered.wasm'
        filter_exports(wasm, filtered, func_exports)
        wasm = filtered

        # get the expected execution results.
        wasm_exec = run_bynterp(wasm, ['--fuzz-exec-before'])

        # eval the wasm.
        # we can use --ignore-external-input because the fuzzer passes in 0 to
        # all params, which is the same as ctor-eval assumes in this mode.
        evalled_wasm = wasm + '.evalled.wasm'
        output = run([in_bin('wasm-ctor-eval'), wasm, '-o', evalled_wasm, '--ctors=' + ctors, '--kept-exports=' + ctors, '--ignore-external-input'] + FEATURE_OPTS)

        # stop here if we could not eval anything at all in the module.
        if '...stopping since could not flatten memory' in output or \
           '...stopping since could not create module instance' in output:
            return
        if '...success' not in output and \
           '...partial evalling success' not in output:
            return
        evalled_wasm_exec = run_bynterp(evalled_wasm, ['--fuzz-exec-before'])

        compare_between_vms(fix_output(wasm_exec), fix_output(evalled_wasm_exec), 'CtorEval')

    @override
    def can_run_on_wasm(self, wasm):
        # ctor-eval modifies exports, because it assumes they are ctors and so
        # are only called once (so if it evals them away, they can be
        # removed). If the wasm might notice that, we cannot run.
        return not wasm_notices_export_changes(wasm)


# see https://github.com/WebAssembly/binaryen/issues/6823#issuecomment-2649122032
# as the interpreter refers to tags by name, two imports of the same Tag give it
# two different names, but they should behave as if they are one.
def wasm_has_duplicate_tags(wasm):
    # as with wasm_notices_export_changes, we could be more precise here and
    # disassemble the wasm.
    binary = open(wasm, 'rb').read()
    # check if we import jstag or wasmtag, which are used in the wasm, so any
    # duplication may hit the github issue mentioned above.
    return binary.count(b'jstag') >= 2 or binary.count(b'wasmtag') >= 2


# Detect whether there is a trap reported before an export call in the output.
def traps_in_instantiation(output):
    trap_index = output.find(TRAP_PREFIX)
    if trap_index == -1:
        # In "fixed" output, traps are replaced with *exception*.
        trap_index = output.find('*exception*')
        if trap_index == -1:
            return False
    export_index = output.find(FUZZ_EXEC_EXPORT_PREFIX)
    if export_index == -1:
        return True
    return trap_index < export_index


# Tests wasm-merge
class Merge(TestCaseHandler):
    frequency = 0.15

    @override
    def handle(self, wasm):
        # generate a second wasm file to merge. note that we intentionally pick
        # a smaller size than the main wasm file, so that reduction is
        # effective (i.e., as we reduce the main wasm to small sizes, we also
        # end up with small secondary wasms)
        # TODO: add imports and exports that connect between the two
        wasm_size = os.stat(wasm).st_size
        second_size = min(wasm_size, random_size())
        second_input = abspath('second_input.dat')
        make_random_input(second_size, second_input)
        second_wasm = abspath('second.wasm')
        run([in_bin('wasm-opt'), second_input, '-ttf', '-o', second_wasm] + GEN_ARGS + FEATURE_OPTS)

        # the second wasm file must not have an export that can influence our
        # execution. the JS exports have that behavior, as when "table-set" is
        # called it will look for the export "table" on which to operate, then
        # imagine we lack that export in the first module but add it in the
        # second, then code that failed before will now use the exported table
        # from the second module (and maybe work). to avoid that, remove the
        # table export, if it exists (and if the first module doesn't export
        # it).
        second_exports = get_exports(second_wasm, ['func', 'table'])
        wasm_exports = get_exports(wasm, ['table'])
        if 'table' in second_exports and 'table' not in wasm_exports:
            filtered = [e for e in second_exports if e != 'table']
            # note we override the set of default things to keep, as we want to
            # remove the table export. doing so might change the behavior of
            # second.wasm, but that is ok.
            filter_exports(second_wasm, second_wasm, filtered, keep_defaults=False)

        # sometimes also optimize the second module
        if random.random() < 0.5:
            opts = get_random_opts()
            run([in_bin('wasm-opt'), second_wasm, '-o', second_wasm, '-all'] + FEATURE_OPTS + opts)

        # merge the wasm files. note that we must pass -all, as even if the two
        # inputs are MVP, the output may have multiple tables and multiple
        # memories (and we must also do that in the commands later down).
        #
        # Use --skip-export-conflicts as we only look at the first module's
        # exports for now - we don't care about the second module's.
        # TODO: compare the second module's exports as well, but we'd need
        #       to handle renaming of conflicting exports.
        merged = abspath('merged.wasm')
        run([in_bin('wasm-merge'), wasm, 'first',
            abspath('second.wasm'), 'second', '-o', merged,
            '--skip-export-conflicts', '-all'])

        if wasm_has_duplicate_tags(merged):
            note_ignored_vm_run('dupe_tags')
            return

        # sometimes also optimize the merged module
        if random.random() < 0.5:
            opts = get_random_opts()
            run([in_bin('wasm-opt'), merged, '-o', merged, '-all'] + opts)

        # verify that merging in the second module did not alter the output.
        output = run_bynterp(wasm, ['--fuzz-exec-before', '-all'])
        if output == IGNORE:
            return
        output = fix_output(output)
        second_output = run_bynterp(second_wasm, ['--fuzz-exec-before', '-all'])
        second_output = fix_output(second_output)
        if second_output == IGNORE:
            return
        merged_output = run_bynterp(merged, ['--fuzz-exec-before', '-all'])
        merged_output = fix_output(merged_output)
        if merged_output == IGNORE:
            return

        # If the second module traps in instantiation, then the merged module
        # must do so as well, regardless of what the first module does. (In
        # contrast, if the first module traps in instantiation, then the normal
        # checks below will ensure the merged module does as well.)
        if traps_in_instantiation(second_output) and \
                not traps_in_instantiation(output):
            # The merged module should also trap in instantiation, but the
            # exports will not be called, so there's nothing else to compare.
            if not traps_in_instantiation(merged_output):
                raise Exception('expected merged module to trap during ' +
                                'instantiation because second module traps ' +
                                'during instantiation')
            compare(merged_output, second_output, 'Merge: second module traps' +
                    ' in instantiation')
            return

        # a complication is that the second module's exports are appended, so we
        # have extra output. to handle that, just prune the tail, so that we
        # only compare the original exports from the first module.
        # TODO: compare the second module's exports to themselves as well, but
        #       they may have been renamed due to overlaps...
        merged_output = merged_output[:len(output)]

        compare_between_vms(output, merged_output, 'Merge')

    @override
    def can_run_on_wasm(self, wasm):
        # wasm-merge combines exports, which can alter their indexes and lead to
        # noticeable differences if the wasm is sensitive to such things, which
        # prevents us from running.
        return not wasm_notices_export_changes(wasm)


FUNC_NAMES_REGEX = re.compile(r'\n [(]func [$](\S+)')


# Tests wasm-split. This also tests that fuzz_shell.js properly executes 2 wasm
# files, which adds coverage for ClusterFuzz (which sometimes runs two wasm
# files in that way).
class Split(TestCaseHandler):
    frequency = 0.1

    @override
    def handle(self, wasm):
        # get the list of function names, some of which we will decide to split
        # out
        wat = get_wat(wasm)
        all_funcs = re.findall(FUNC_NAMES_REGEX, wat)

        # get the original output before splitting
        output = run_d8_wasm(wasm)
        output = fix_output(output)

        # find the names of the exports. we need this because when we split the
        # module then new exports appear to connect the two halves of the
        # original module. we do not want to call all the exports on the new
        # primary module, but only the original ones.
        exports = []
        for line in output.splitlines():
            if FUZZ_EXEC_EXPORT_PREFIX in line:
                exports.append(get_export_from_export_line(line))

        # pick which to split out, with a random rate of picking (biased towards
        # 0.5).
        rate = (random.random() + random.random()) / 2
        split_funcs = []
        for func in all_funcs:
            if random.random() < rate:
                split_funcs.append(func)

        if not split_funcs:
            # nothing to split out
            return

        # split the wasm into two
        primary = wasm + '.primary.wasm'
        secondary = wasm + '.secondary.wasm'

        # we require reference types, because that allows us to create our own
        # table. without that we use the existing table, and that may interact
        # with user code in odd ways (it really only works with the particular
        # form of table+segments that LLVM emits, and not with random fuzzer
        # content).
        split_feature_opts = FEATURE_OPTS + ['--enable-reference-types']

        run([in_bin('wasm-split'), wasm, '--split',
             '--split-funcs', ','.join(split_funcs),
             # make the new exports easily identifiable, as we need to ignore
             # them in part of fuzz_shell.js
             '--export-prefix=__fuzz_split_',
             '--primary-output', primary,
             '--secondary-output', secondary] + split_feature_opts)

        # sometimes also optimize the split modules
        optimized = False

        def optimize(name):
            # do not optimize if it would change the ABI
            if CLOSED_WORLD:
                return name
            # TODO: use other optimizations here, but we'd need to be careful of
            #       anything that can alter the ABI, and also current
            #       limitations of open-world optimizations (see discussion in
            #       https://github.com/WebAssembly/binaryen/pull/6660)
            opts = ['-O3']
            new_name = name + '.opt.wasm'
            run([in_bin('wasm-opt'), name, '-o', new_name, '-all'] + opts + split_feature_opts)
            nonlocal optimized
            optimized = True
            return new_name

        if random.random() < 0.5:
            primary = optimize(primary)
        if random.random() < 0.5:
            secondary = optimize(secondary)

        # prepare the list of exports to call. the format is
        #
        #  exports:A,B,C
        #
        exports_to_call = 'exports:' + ','.join(exports)

        # get the output from the split modules, linking them using JS
        # TODO run liftoff/turboshaft/etc.
        args = [
            secondary,
            exports_to_call,
            '--fuzz-split',
        ]
        linked_output = run_d8_wasm(primary, args=args)
        linked_output = fix_output(linked_output)

        # see D8.can_compare_to_self: we cannot compare optimized outputs if
        # NaNs are allowed, as the optimizer can modify NaNs differently than
        # the JS engine.
        if not (NANS and optimized):
            compare_between_vms(output, linked_output, 'Split')

    @override
    def can_run_on_wasm(self, wasm):
        # to run the split wasm we use JS, that is, JS links the exports of one
        # to the imports of the other, etc. since we run in JS, the wasm must be
        # valid for JS.
        if not LEGALIZE:
            return False

        # see D8.can_run
        return all_disallowed(DISALLOWED_FEATURES_IN_V8)


# Check that the text format round-trips without error.
class RoundtripText(TestCaseHandler):
    frequency = 0.05

    @override
    def handle(self, wasm):
        # use name-types because in wasm GC we can end up truncating the default
        # names which are very long, causing names to collide and the wast to be
        # invalid
        # FIXME: run name-types by default during load?
        run([in_bin('wasm-opt'), wasm, '--name-types', '-S', '-o', abspath('a.wast')] + FEATURE_OPTS)
        run([in_bin('wasm-opt'), abspath('a.wast')] + FEATURE_OPTS)


# The error shown in V8 when a module fails to instantiate.
INSTANTIATE_ERROR = 'exception thrown: failed to instantiate module'


# Fuzz in a near-identical manner to how we fuzz on ClusterFuzz. This is mainly
# to see that fuzzing that way works properly (it likely won't catch anything
# the other fuzzers here catch, though it is possible). That is, running this
# script continuously will give continuous cover that ClusterFuzz should be
# running ok.
#
# Note that this is *not* deterministic like the other fuzzers: it runs run.py
# like ClusterFuzz does, and that generates its own random data. If a bug is
# caught here, it must be reduced manually.
class ClusterFuzz(TestCaseHandler):
    frequency = 0.1

    # Use handle_pair over handle because we don't use these wasm files anyhow,
    # we generate our own using run.py. If we used handle, we'd be called twice
    # for each iteration (once for each of the wasm files we ignore), which is
    # confusing.
    @override
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        # Do not run ClusterFuzz in the first seconds of fuzzing: the first time
        # it runs is very slow (to build the bundle), which is annoying when you
        # are just starting the fuzzer and looking for any obvious problems.
        # Check this here as opposed to in e.g. can_run_on_wasm to avoid
        # changing the observed sequence of random numbers before and after this
        # threshold, which could interfere with bug reproduction.
        seconds = 30
        if time.time() - start_time < seconds:
            return

        self.ensure()

        # NO RANDOM DATA SHOULD BE USED BELOW THIS POINT

        # run.py() should emit these two files. Delete them to make sure they
        # are created by run.py() in the next step.
        fuzz_file = 'fuzz-binaryen-1.js'
        flags_file = 'flags-binaryen-1.js'
        for f in [fuzz_file, flags_file]:
            if os.path.exists(f):
                os.unlink(f)

        # Call run.py(), similarly to how ClusterFuzz does.
        run([sys.executable,
             os.path.join(self.clusterfuzz_dir, 'run.py'),
             '--output_dir=' + os.getcwd(),
             '--no_of_files=1',
             # Do not retry on wasm-opt errors: we want to investigate
             # them.
             '--no_retry'])

        # We should see the two files.
        assert os.path.exists(fuzz_file)
        assert os.path.exists(flags_file)

        # We'll use the fuzz file a few times below in commands.
        fuzz_file = os.path.abspath(fuzz_file)

        # Run the testcase in V8, similarly to how ClusterFuzz does.
        cmd = [shared.V8]
        # The flags are given in the flags file - we do *not* use our normal
        # flags here!
        with open(flags_file) as f:
            flags = f.read()
        cmd += flags.split(' ')
        # Get V8's extra fuzzing flags, the same as the ClusterFuzz runner does
        # (as can be seen from the testcases having --fuzzing and a lot of other
        # flags as well).
        cmd += get_v8_extra_flags()
        # Run the fuzz file, which contains a modified fuzz_shell.js - we do
        # *not* run fuzz_shell.js normally.
        cmd.append(fuzz_file)
        # No wasm file needs to be provided: it is hardcoded into the JS. Note
        # that we use run_vm(), which will ignore known issues in our output and
        # in V8. Those issues may cause V8 to e.g. reject a binary we emit that
        # is invalid, but that should not be a problem for ClusterFuzz (it isn't
        # a crash).
        output = run_vm(cmd)

        # Verify that we called something, if the fuzzer emitted a func export
        # (rarely, none might exist), unless we've decided to ignore the entire
        # run, or if the wasm errored during instantiation, which can happen due
        # to a testcase with a segment out of bounds, say.
        if output != IGNORE and not output.startswith(INSTANTIATE_ERROR):
            # Do the work to find if there were function exports: extract the
            # wasm from the JS, and process it.
            run([sys.executable,
                 in_binaryen('scripts', 'clusterfuzz', 'extract_wasms.py'),
                 fuzz_file,
                 'extracted'])
            if get_exports('extracted.0.wasm', ['func']):
                assert FUZZ_EXEC_EXPORT_PREFIX in output

    def ensure(self):
        # The first time we actually run, set things up: make a bundle like the
        # one ClusterFuzz receives, and unpack it for execution into a dir. The
        # existence of that dir shows we've ensured all we need.
        if hasattr(self, 'clusterfuzz_dir'):
            return

        self.clusterfuzz_dir = 'clusterfuzz'
        if os.path.exists(self.clusterfuzz_dir):
            shutil.rmtree(self.clusterfuzz_dir)
        os.mkdir(self.clusterfuzz_dir)

        print('Bundling for ClusterFuzz')
        bundle = 'fuzz_opt_clusterfuzz_bundle.tgz'
        run([in_binaryen('scripts', 'bundle_clusterfuzz.py'), bundle])

        print('Unpacking for ClusterFuzz')
        tar = tarfile.open(bundle, "r:gz")
        tar.extractall(path=self.clusterfuzz_dir)
        tar.close()


# Generates two wasm and tests interesting interactions between them. This is a
# little similar to Split(), but rather than split one wasm file into two and
# test that, we start with two.
#
# Fuzzing failures here is a little trickier, as there are two wasm files.
# You can reduce the primary file by finding the secondary one in the log
# (usually out/test/second.wasm), copy that to the side, and add
#
#   BINARYEN_SECOND_WASM=${saved_second}
#
# in the env. That will keep the secondary wasm fixed as you reduce the primary
# one.
#
# Note it may be better to reduce the second one first, so it imports less from
# the first (otherwise, when the second one imports many things, the first will
# fail to remove exports that are used). To reduce the second one, set
#
#   BINARYEN_FIRST_WASM=${saved_first}
#
# The reduce.sh script will then do the right thing, using that as the first
# wasm, and reducing on the second one, if you replace "original.wasm" in the
# reduction command (the command that this fuzzer script recommended that you
# run) with "second.wasm" as needed.
#
# In both cases, make sure to copy the files to a saved location first (do not
# use a path to the scratch files that get constantly overwritten). The full
# process might look like this:
#
#  * cp out/test/original.wasm first.wasm
#  * cp out/test/second.wasm second.wasm
#  * BINARYEN_FIRST_WASM=`pwd`/first.wasm [copied reducer command, replacing
#                                          original.wasm with `pwd`/second.wasm]
#  * cp out/test/w.wasm second.reduced.wasm
#  * BINARYEN_SECOND_WASM=`pwd`/second.reduced.wasm [copied reducer command,
#                                                    replacing original.wasm
#                                                    with `pwd`/first.wasm]
#
class Two(TestCaseHandler):
    # Run at relatively high priority, as this is the main place we check cross-
    # module interactions.
    frequency = 1  # TODO: We may want even higher priority here

    @override
    def handle(self, wasm):
        # Generate a second wasm file. (For fuzzing, we may be given one, but we
        # still do the work to prepare to generate it, as that consumes random
        # values, and we don't want that to affect anything later.)
        second_wasm = abspath('second.wasm')
        second_input = abspath('second_input.dat')
        second_size = random_size()
        make_random_input(second_size, second_input)
        args = [second_input, '-ttf']
        # Most of the time, use the first wasm as an import to the second.
        if random.random() < 0.8:
            args += ['--fuzz-import=' + wasm]

        given = os.environ.get('BINARYEN_SECOND_WASM')
        if not given:
            print('Generate second wasm')
            run([in_bin('wasm-opt'), '-o', second_wasm] + args + GEN_ARGS + FEATURE_OPTS)
        else:
            print(f'Use given second wasm {given}')
            shutil.copyfile(given, second_wasm)

        # Run the wasm.
        #
        # Note that we *cannot* run each wasm file separately and compare those
        # to the combined output, as fuzz_shell.js intentionally allows calls
        # *between* the wasm files, through JS APIs like call-export*. So all we
        # do here is see the combined, linked behavior, and then later below we
        # see that that behavior remains even after optimizations.
        output = run_bynterp(wasm, args=['--fuzz-exec-before', f'--fuzz-exec-second={second_wasm}'])

        # Check if we trapped during instantiation.
        if traps_in_instantiation(output):
            # We may fail to instantiate the modules for valid reasons, such as
            # an active segment being out of bounds. There is no point to
            # continue in such cases, as no exports are called.
            note_ignored_vm_run('Two instantiate error')
            return

        if output == IGNORE:
            # There is no point to continue since we can't compare this output
            # to anything.
            return

        # Make sure that we actually executed all exports from both
        # wasm files.
        exports = get_exports(wasm, ['func', 'global'])
        exports += get_exports(second_wasm, ['func', 'global'])
        calls_in_output = output.count(FUZZ_EXEC_EXPORT_PREFIX)
        if calls_in_output == 0:
            print(f'warning: no calls in output. output:\n{output}')
        assert calls_in_output == len(exports), exports

        # Merge the files and run them that way. The result should be the same,
        # even if we optimize. TODO: merge (no pun intended) the rest of Merge
        # into here.
        merged = abspath('merged.wasm')
        run([in_bin('wasm-merge'), wasm, 'primary', second_wasm, 'secondary',
            '-o', merged, '--rename-export-conflicts', '-all'])

        # Usually also optimize the merged module. Optimizations are very
        # interesting here, because after merging we can safely do even closed-
        # world optimizations, making very aggressive changes that should still
        # behave the same as before merging.
        if random.random() < 0.8:
            merged_opt = abspath('merged.opt.wasm')
            opts = get_random_opts()
            run([in_bin('wasm-opt'), merged, '-o', merged_opt, '-all'] + opts)
            merged = merged_opt

        if not wasm_notices_export_changes(merged):
            # wasm-merge combines exports, which can alter their indexes and
            # lead to noticeable differences if the wasm is sensitive to such
            # things. We only compare the output if that is not an issue.
            merged_output = run_bynterp(merged, args=['--fuzz-exec-before', '-all'])

            if merged_output == IGNORE:
                # The original output was ok, but after merging it becomes
                # something we must ignore. This can happen when we optimize, if
                # the optimizer reorders a normal trap (say a null exception)
                # with a host limit trap (say an allocation limit). This can
                # also happen because stack limits on calls change slightly when
                # we go from cross-module calls to within-module calls. There
                # is nothing to check in this case.
                pass
            else:
                self.compare_to_merged_output(output, merged_output)

        # The rest of the testing here depends on being to optimize the
        # two modules independently, which closed-world can break.
        if CLOSED_WORLD:
            return

        # Fix up the normal output for later comparisons.
        output = fix_output(output)

        # We can optimize and compare the results. Optimize at least one of
        # the two.
        wasms = [wasm, second_wasm]
        for i in range(random.randint(1, 2)):
            wasm_index = random.randint(0, 1)
            name = wasms[wasm_index]
            new_name = name + f'.opt{i}.wasm'
            opts = get_random_opts()
            run([in_bin('wasm-opt'), name, '-o', new_name] + opts + FEATURE_OPTS)
            wasms[wasm_index] = new_name

        # Run again, and compare the output
        optimized_output = run_bynterp(wasms[0], args=['--fuzz-exec-before', f'--fuzz-exec-second={wasms[1]}'])
        optimized_output = fix_output(optimized_output)

        compare(output, optimized_output, 'Two-Opt')

        # If we can, also test in V8. We also cannot compare if there are NaNs
        # (as optimizations can lead to different outputs), and we must
        # disallow some features.
        # TODO: relax some of these
        if NANS or not all_disallowed(DISALLOWED_FEATURES_IN_V8):
            return

        output = run_d8_wasm(wasm, args=[second_wasm])

        if output == IGNORE:
            return

        # We ruled out things we must ignore, like host limitations, and also
        # exited earlier on a deterministic instantiation error, so there should
        # be no such error in V8.
        assert not output.startswith(INSTANTIATE_ERROR)

        output = fix_output(output)

        optimized_output = run_d8_wasm(wasms[0], args=[wasms[1]])
        optimized_output = fix_output(optimized_output)

        compare(output, optimized_output, 'Two-V8')

    @staticmethod
    def compare_to_merged_output(output, merged_output):
        # Comparing the original output from two files to the output after
        # merging them is not trivial. First, remove the extra logging that
        # --fuzz-exec-second adds.
        output = output.replace('[fuzz-exec] running second module\n', '')

        # Fix up both outputs.
        output = fix_output(output)
        merged_output = fix_output(merged_output)

        # Finally, align the export names. We merged with
        # --rename-export-conflicts, so that all exports remain exported,
        # allowing a full comparison, but we do need to handle the different
        # names. We do so by matching the export names in the logging.
        output_lines = output.splitlines()
        merged_output_lines = merged_output.splitlines()

        if len(output_lines) != len(merged_output_lines):
            # The line counts don't even match. Just compare them, which will
            # emit a nice error for that.
            compare(output, merged_output, 'Two-Counts')
            assert False, 'we should have errored on the line counts'

        for i in range(len(output_lines)):
            a = output_lines[i]
            b = merged_output_lines[i]
            if a == b:
                continue
            if a.startswith(FUZZ_EXEC_EXPORT_PREFIX):
                # Fix up
                #   [fuzz-exec] export foo/bar
                # for different foo/bar. Just copy the original.
                assert b.startswith(FUZZ_EXEC_EXPORT_PREFIX)
                merged_output_lines[i] = output_lines[i]
            elif a.startswith(FUZZ_EXEC_NOTE_RESULT):
                # Fix up
                #   [fuzz-exec] note result: foo/bar => 42
                # for different foo/bar. We do not want to copy the result here,
                # which might differ (that would be a bug we want to find).
                assert b.startswith(FUZZ_EXEC_NOTE_RESULT)
                assert a.count(' => ') == 1
                assert b.count(' => ') == 1
                a_prefix, a_result = a.split(' => ')
                b_prefix, b_result = b.split(' => ')
                # Copy a's prefix with b's result.
                merged_output_lines[i] = a_prefix + ' => ' + b_result

        merged_output = '\n'.join(merged_output_lines)

        compare(output, merged_output, 'Two-Merged')


# Test --fuzz-preserve-imports-exports on random inputs. This should never
# modify imports or exports.
class PreserveImportsExportsRandom(TestCaseHandler):
    frequency = 0.1

    @override
    def handle(self, wasm):
        # We will later verify that no imports or exports changed, by comparing
        # to the unprocessed original text.
        original = run([in_bin('wasm-opt'), wasm] + FEATURE_OPTS + ['--print'])

        # We leave if the module has (ref exn) in struct fields (because we have
        # no way to generate an exn in a non-function context, and if we picked
        # that struct for a global, we'd end up needing a (ref exn) in the
        # global scope, which is impossible). The fuzzer is designed to be
        # careful not to emit that in testcases, but after the optimizer runs,
        # we may end up with struct fields getting refined to that, so we need
        # this extra check (which should be hit very rarely).
        structs = [line for line in original.split('\n') if '(struct ' in line]
        if '(ref exn)' in '\n'.join(structs):
            note_ignored_vm_run('has non-nullable exn in struct')
            return

        # Generate some random input data.
        data = abspath('preserve_input.dat')
        make_random_input(random_size(), data)

        # Process the existing wasm file.
        processed = run([in_bin('wasm-opt'), data] + FEATURE_OPTS + [
            '-ttf',
            '--fuzz-preserve-imports-exports',
            '--initial-fuzz=' + wasm,
            '--print',
        ])

        def get_relevant_lines(wat):
            # Imports and exports are relevant.
            lines = [line for line in wat.splitlines() if '(export ' in line or '(import ' in line]

            # Ignore type names, which may vary (e.g. one file may have $5 and
            # another may call the same type $17).
            lines = [re.sub(r'[(]type [$][0-9a-zA-Z_$]+[)]', '', line) for line in lines]

            return '\n'.join(lines)

        compare(get_relevant_lines(original), get_relevant_lines(processed), 'Preserve')


# Test --fuzz-preserve-imports-exports on a realistic js+wasm input. Unlike
# PreserveImportsExportsRandom which starts with a random file and modifies it,
# this starts with a fixed js+wasm testcase, known to work and to have
# interesting operations on the js/wasm boundary, and then randomly modifies
# the wasm. This simulates how an external fuzzer could use binaryen to modify
# its known-working testcases (parallel to how we test ClusterFuzz here).
#
# This reads wasm+js combinations from the test/js_wasm directory, so as new
# testcases are added there, this will fuzz them.
#
# Note that bugs found by this fuzzer require BINARYEN_TRUST_GIVEN_WASM=1 in the
# env for reduction. TODO: simplify this
class PreserveImportsExportsJS(TestCaseHandler):
    frequency = 1

    @override
    def handle_pair(self, input, before_wasm, after_wasm, opts):
        try:
            self.do_handle_pair(input, before_wasm, after_wasm, opts)
        except Exception as e:
            if not os.environ.get('BINARYEN_TRUST_GIVEN_WASM'):
                # We errored, and we were not given a wasm file to trust as we
                # reduce, so this is the first time we hit an error. Save the
                # pre wasm file, the one we began with, as `before_wasm`, so
                # that the reducer will make us proceed exactly from there.
                shutil.copyfile(self.pre_wasm, before_wasm)
            raise e

    def do_handle_pair(self, input, before_wasm, after_wasm, opts):
        # Some of the time use a custom input. The normal inputs the fuzzer
        # generates are in range INPUT_SIZE_MIN-INPUT_SIZE_MAX, which is good
        # for new testcases, but the more changes we make to js+wasm testcases,
        # the more chance we have to break things entirely (the js/wasm boundary
        # is fragile). It is useful to also fuzz smaller sizes.
        if random.random() < 0.25:
            size = random.randint(0, INPUT_SIZE_MIN * 2)
            make_random_input(size, input)

        # Pick a js+wasm pair.
        js_files = list(pathlib.Path(in_binaryen('test', 'js_wasm')).glob('*.mjs'))
        js_file = str(random.choice(js_files))
        print(f'js file: {js_file}')
        wat_file = str(pathlib.Path(js_file).with_suffix('.wat'))

        # Verify the wat works with our features
        try:
            run([in_bin('wasm-opt'), wat_file] + FEATURE_OPTS,
                stderr=subprocess.PIPE,
                silent=True)
        except Exception:
            note_ignored_vm_run('PreserveImportsExportsJS: features not compatible with js+wasm')
            return

        # Make sure the testcase runs by itself - there should be no invalid
        # testcases.
        original_wasm = 'orig.wasm'
        run([in_bin('wasm-opt'), wat_file, '-o', original_wasm] + FEATURE_OPTS)
        D8().run_js(js_file, original_wasm)

        # Modify the initial wat to get the pre-optimizations wasm.
        pre_wasm = abspath('pre.wasm')
        gen_args = [
            input,
            '-ttf',
            '--fuzz-preserve-imports-exports',
            '--initial-fuzz=' + wat_file,
            '-o', pre_wasm,
            '-g',
        ]
        # We do not copy all of GEN_ARGS, as we don't need e.g. legalization.
        if not NANS:
            # TODO: do we also need this in each reduction step?
            gen_args += ['--denan']
        run([in_bin('wasm-opt')] + gen_args + FEATURE_OPTS)

        # We successfully generated pre_wasm; stash it for possible reduction
        # purposes later.
        self.pre_wasm = pre_wasm

        # If we were given a wasm file, use that instead of all the above. We
        # do this now, after creating pre_wasm, because we still need to consume
        # all the randomness normally.
        if os.environ.get('BINARYEN_TRUST_GIVEN_WASM'):
            print('using given wasm', before_wasm)
            pre_wasm = before_wasm

        # Pick a vm and run before we optimize the wasm.
        vms = [
            D8(),
            D8Liftoff(),
            D8Turboshaft(),
        ]
        pre_vm = random.choice(vms)
        pre = self.do_run(pre_vm, js_file, pre_wasm)

        # Optimize.
        post_wasm = abspath('post.wasm')
        cmd = [in_bin('wasm-opt'), pre_wasm, '-o', post_wasm] + opts + FEATURE_OPTS
        print(' '.join(cmd))
        proc = subprocess.run(cmd, capture_output=True, text=True)
        if proc.returncode:
            if 'Invalid configureAll' in proc.stderr:
                # We have a hard error on unfamiliar configureAll patterns atm.
                # Mutation of configureAll will easily break that pattern, so we
                # must ignore such cases.
                note_ignored_vm_run('PreserveImportsExportsJS: bad configureAll')
                return

            # Anything else is a problem.
            print(proc.stderr)
            raise Exception('opts failed')

        # Run after opts, in a random vm.
        post_vm = random.choice(vms)
        post = self.do_run(post_vm, js_file, post_wasm)

        # Compare, if we can.
        if pre_vm.can_compare_to_other(post_vm):
            compare(pre, post, 'PreserveImportsExportsJS')

    @staticmethod
    def do_run(vm, js, wasm):
        out = vm.run_js(js, wasm, checked=False)

        # VM crashes are actual issues we want to find.
        if '(core dumped)' in out or 'Received signal' in out or '== C stack trace ==' in out or '== JS stack trace ==' in out:
            raise Exception(f"VM crash:\n\n{out}")

        # Clean up stack traces.
        cleaned = []
        for line in out.splitlines():
            if 'RuntimeError:' in line or 'TypeError:' in line:
                # This is part of an error like
                #
                #  wasm-function[2]:0x273: RuntimeError: unreachable
                #
                # We must ignore the binary location, which opts can change. We
                # must also remove the specific trap, as Binaryen can change
                # that.
                line = 'TRAP'
            elif line.startswith('    at '):
                # This is part of a stack trace like
                #
                #     at wasm://wasm/12345678:wasm-function[42]:0x123
                #     at (<anonymous>)
                #     at file.js
                #
                # Ignore it, as details of traces differ based on optimizations.
                continue
            cleaned.append(line)
        cleaned = '\n'.join(cleaned)

        # Clean up function references, which can differ after opts, things like
        #
        #  function 77() { [native code] }
        #
        cleaned = re.sub(r'function \d+\(\) ', 'function <ID>() ', cleaned)
        return cleaned

    @override
    def can_run_on_wasm(self, wasm):
        return all_disallowed(DISALLOWED_FEATURES_IN_V8)


# Test that we preserve branch hints properly. The invariant that we test here
# is that, given correct branch hints (that is, the input wasm's branch hints
# are always correct: a branch is taken iff the hint is that it is taken), then
# the optimizer does not end up with incorrect branch hints. It is fine if the
# optimizer removes some hints (it may remove entire chunks of code in DCE, for
# example, and it may find ways to simplify code so fewer things execute), but
# it should not emit a branch hint that is wrong - if it is not certain, it
# should remove the branch hint.
#
# Note that bugs found by this fuzzer tend to require the following during
# reducing: BINARYEN_TRUST_GIVEN_WASM=1 in the env, and --text as a parameter.
class BranchHintPreservation(TestCaseHandler):
    frequency = 0.1

    @override
    def handle(self, wasm):
        # Generate an instrumented wasm.
        instrumented = wasm + '.inst.wasm'
        run([
            in_bin('wasm-opt'),
            wasm,
            '-o', instrumented,
            # Add random branch hints (so we have something to work with).
            '--randomize-branch-hints',
            # Instrument them with logging.
            '--instrument-branch-hints',
            '-g',
        ] + FEATURE_OPTS)

        # Collect the logging.
        out = run_bynterp(instrumented, ['--fuzz-exec-before', '-all'])

        # Process the output. We look at the lines like this:
        #
        #   [LoggingExternalInterface log-branch 1 0 0]
        #
        # where the three integers are: ID, predicted, actual.
        all_ids = set()
        bad_ids = set()
        LOG_BRANCH_PREFIX = '[LoggingExternalInterface log-branch'
        for line in out.splitlines():
            if line.startswith(LOG_BRANCH_PREFIX):
                # (1:-1 strips away the '[', ']' at the edges)
                _, _, actual, hint, id_ = line[1:-1].split(' ')
                all_ids.add(id_)
                if hint != actual:
                    # This hint was misleading.
                    bad_ids.add(id_)

        # If no good ids remain, there is nothing to test (no hints will remain
        # later down, after we remove bad ones).
        if bad_ids == all_ids:
            note_ignored_vm_run('no good ids')
            return

        # Generate proper hints for testing: A wasm file with 100% valid branch
        # hints, and instrumentation to verify that.
        de_instrumented = wasm + '.de_inst.wasm'
        args = [
            in_bin('wasm-opt'),
            instrumented,
            '-o', de_instrumented,
        ]
        # Remove the bad ids (using the instrumentation to identify them by ID).
        if bad_ids:
            args += [
                '--delete-branch-hints=' + ','.join(bad_ids),
            ]
        args += [
            # Remove all prior instrumentation, so it does not confuse us later
            # when we log our final hints, and also so it does not inhibit
            # optimizations.
            '--deinstrument-branch-hints',
            '-g',
        ] + FEATURE_OPTS
        run(args)

        # Add optimizations to see if things break.
        opted = wasm + '.opted.wasm'
        args = [
            in_bin('wasm-opt'),
            de_instrumented,
            '-o', opted,
            '-g',

            # Some passes are just skipped, as they do not modify ifs or brs,
            # but they do break the invariant of not adding bad branch hints.
            # There are two main issues here:
            # * Moving code around, possibly causing it to start to execute if
            #   it previously was not reached due to a trap (a branch hint
            #   seems to have no effects in the optimizer, so it will do such
            #   movements). And if it starts to execute and is a wrong hint, we
            #   get an invalid fuzzer finding.
            #   * LICM moves code out of loops.
            '--skip-pass=licm',
            #   * HeapStoreOptimization moves struct.sets closer to struct.news.
            '--skip-pass=heap-store-optimization',
            #   * MergeBlocks moves code out of inner blocks to outer blocks.
            '--skip-pass=merge-blocks',
            #   * Monomorphize can subtly reorder code:
            #
            #       (call $foo
            #         (select
            #           (i32.div_s ..which will trap..)
            #           (if with branch hint)
            #     =>
            #       (call $foo_1
            #         (if with branch hint)
            #
            #     where $foo_1 receives the if's result and uses it in the
            #     ("reverse-inlined") select. Now the if executes first, when
            #     previously the trap stopped it.
            '--skip-pass=monomorphize',
            '--skip-pass=monomorphize-always',
            # SimplifyGlobals finds globals that are "read only to be written",
            # and can remove the ifs that do so:
            #
            #         if (foo) { foo = 1 }
            #     =>
            #         if (0) {}
            #
            # This is valid if the global's value is never read otherwise, but
            # it does alter the if's behavior.
            '--skip-pass=simplify-globals',
            '--skip-pass=simplify-globals-optimizing',

            # * Merging/folding code. When we do so, code identical in content
            #   but differing in metadata will end up with the metadata from one
            #   of the copies, which might be wrong (we follow LLVM here, see
            #   details in the passes).
            #   * CodeFolding merges code blocks inside functions.
            '--skip-pass=code-folding',
            #   * DuplicateFunctionElimination merges functions.
            '--skip-pass=duplicate-function-elimination',

            # Some passes break the invariant in some cases, but we do not want
            # to skip them entirely, as they have other things we need to fuzz.
            # We add pass-args for them:
            # * Do not fold inside OptimizeInstructions.
            '--pass-arg=optimize-instructions-never-fold-or-reorder',
            # * Do not unconditionalize code in RemoveUnusedBrs.
            '--pass-arg=remove-unused-brs-never-unconditionalize',

        ] + get_random_opts() + FEATURE_OPTS
        run(args)

        # Add instrumentation, to see if any branch hints are wrong after
        # optimizations. We must do this in a separate invocation from the
        # optimizations due to flags like --converge (which would instrument
        # multiple times).
        final = wasm + '.final.wasm'
        args = [
            in_bin('wasm-opt'),
            opted,
            '-o', final,
            '--instrument-branch-hints',
            '-g',
        ] + FEATURE_OPTS
        run(args)

        # Run the final wasm.
        out = run_bynterp(final, ['--fuzz-exec-before', '-all'])

        # Preprocess the logging. We must discard all lines from functions that
        # trap, because we are fuzzing branch hints, which are not an effect,
        # and so they can be reordered with traps; consider this:
        #
        #  (i32.add
        #    (block
        #      (if (X) (unreachable)
        #      (i32.const 10)
        #    )
        #    (block
        #      (@metadata.code.branch_hint "\00")
        #      (if (Y) (unreachable)
        #      (i32.const 20)
        #    )
        #  )
        #
        # It is ok to reorder traps, so the optimizer might flip the arms of
        # this add (imagine other code inside the arms justified that). That
        # reordering is fine since the branch hint has no effect that the
        # optimizer needs to care about. However, after we instrument, there
        # *is* an effect, the visible logging, so if X is true we trap and do
        # not log a branch hint, but if we reorder, we do log, then trap.
        #
        # Note that this problem is specific to traps, because the optimizer can
        # reorder them, and does not care about identity.
        #
        # To handle this, gather lines for each call, and then see which groups
        # end in traps. (Initialize the list of groups with an empty group, for
        # any logging before the first call.)
        line_groups = [['before calls']]
        for line in out.splitlines():
            if line.startswith(FUZZ_EXEC_EXPORT_PREFIX):
                line_groups.append([line])
            else:
                line_groups[-1].append(line)

        # No bad hints should pop up after optimizations.
        for group in line_groups:
            if not group or group[-1] == '[trap unreachable]':
                continue
            for line in group:
                if line.startswith(LOG_BRANCH_PREFIX):
                    _, _, actual, hint, id_ = line[1:-1].split(' ')
                    hint = int(hint)
                    actual = int(actual)
                    assert hint in {0, 1}
                    # We do not care about the integer value of the condition,
                    # only if it was 0 or non-zero.
                    actual = (actual != 0)
                    assert hint == actual, 'Bad hint after optimizations'


# The global list of all test case handlers
testcase_handlers = [
    FuzzExec(),
    CompareVMs(),
    CheckDeterminism(),
    Wasm2JS(),
    TrapsNeverHappen(),
    CtorEval(),
    Merge(),
    # Split(), # https://github.com/WebAssembly/binaryen/issues/8510
    RoundtripText(),
    ClusterFuzz(),
    Two(),
    PreserveImportsExportsRandom(),
    PreserveImportsExportsJS(),
    BranchHintPreservation(),
]


# Do one test, given an input file for -ttf and some optimizations to run
def test_one(random_input, given_wasm):
    randomize_pass_debug()
    randomize_feature_opts()
    randomize_fuzz_settings()
    pick_initial_contents()

    opts = get_random_opts()
    print('randomized opts:', '\n  ' + '\n  '.join(opts))
    print()

    if given_wasm:
        # We are given a wasm file to operate on. By default we modify it in the
        # usual ways, like running DeNAN on it, which is important in many cases
        # (imagine the reducer generates a NAN, then we need to restore the
        # property of not having any). However, in some cases we do need to
        # trust the wasm is correct, or it is simpler to debug things without
        # constant changes in each reduction cycle, so we have an env var to
        # control that, BINARYEN_TRUST_GIVEN_WASM.
        if os.environ.get('BINARYEN_TRUST_GIVEN_WASM'):
            shutil.copyfile(given_wasm, abspath('a.wasm'))
        else:
            try:
                run([in_bin('wasm-opt'), given_wasm, '-o', abspath('a.wasm')] + GEN_ARGS + FEATURE_OPTS)
            except Exception as e:
                print("Internal error in fuzzer! Could not run given wasm")
                raise e
    else:
        # emit the target features section so that reduction can work later,
        # without needing to specify the features
        generate_command = [in_bin('wasm-opt'), random_input, '-ttf', '-o', abspath('a.wasm')] + GEN_ARGS + FEATURE_OPTS
        if INITIAL_CONTENTS:
            generate_command += ['--initial-fuzz=' + INITIAL_CONTENTS]
        if PRINT_WATS:
            printed = run(generate_command + ['--print'])
            with open('a.printed.wast', 'w') as f:
                f.write(printed)
        else:
            run(generate_command)
    wasm_size = os.stat('a.wasm').st_size
    bytes = wasm_size
    print('pre wasm size:', wasm_size)
    update_feature_opts('a.wasm')

    # create a second (optimized) wasm for handlers that want to look at pairs.
    generate_command = [in_bin('wasm-opt'), abspath('a.wasm'), '-o', abspath('b.wasm')] + opts + FUZZ_OPTS + FEATURE_OPTS
    if PRINT_WATS:
        printed = run(generate_command + ['--print'])
        with open('b.printed.wast', 'w') as f:
            f.write(printed)
    else:
        run(generate_command)
    wasm_size = os.stat('b.wasm').st_size
    bytes += wasm_size
    print('post wasm size:', wasm_size)

    # First, find which handlers can even run here. Note that we check a.wasm
    # and not b.wasm (optimizations do not change fuzzability).
    relevant_handlers = [handler for handler in testcase_handlers if not hasattr(handler, 'get_commands') and handler.can_run_on_wasm('a.wasm')]
    if len(relevant_handlers) == 0:
        return 0
    # filter by frequency
    filtered_handlers = [handler for handler in relevant_handlers if random.random() < handler.frequency]
    if len(filtered_handlers) == 0:
        # pick at least one, to not waste the effort we put into making the wasm
        filtered_handlers = [random.choice(relevant_handlers)]
    # run only one of the handlers. this is less efficient in terms of how many
    # handlers we run, but more varied in the wasms we see. it also avoids the
    # annoyance of running two testcase handlers on the same testcase during
    # reduction (it is much simpler to reduce when only the failing thing is
    # being run).
    testcase_handler = random.choice(filtered_handlers)
    assert testcase_handler.can_run_on_wasm('a.wasm')
    print('running testcase handler:', testcase_handler.__class__.__name__)
    testcase_handler.increment_runs()

    # let the testcase handler handle this testcase however it wants. in this case we give it
    # the input and both wasms.
    testcase_handler.handle_pair(input=random_input, before_wasm=abspath('a.wasm'), after_wasm=abspath('b.wasm'), opts=opts + FEATURE_OPTS)

    return bytes


def write_commands(commands, filename):
    with open(filename, 'w') as f:
        f.write('set -e\n')
        for command in commands:
            f.write(f'echo "{command}"\n')
            pre = 'BINARYEN_PASS_DEBUG=%s ' % (os.environ.get('BINARYEN_PASS_DEBUG') or '0')
            f.write(pre + command + ' &> /dev/null\n')
        f.write('echo "ok"\n')


# main

opt_choices = [
    (),
    ('-O1',), ('-O2',), ('-O3',), ('-O4',), ('-Os',), ('-Oz',),
    ("--abstract-type-refining",),
    ("--cfp",),
    ("--cfp-reftest",),
    ("--coalesce-locals",),
    # XXX slow, non-default ("--coalesce-locals-learning",),
    ("--code-pushing",),
    ("--code-folding",),
    ("--const-hoisting",),
    ("--dae",),
    ("--dae-optimizing",),
    ("--dae2",),
    ("--dce",),
    ("--directize",),
    ("--discard-global-effects",),
    ("--flatten", "--dfo",),
    ("--duplicate-function-elimination",),
    ("--flatten",),
    # ("--fpcast-emu",), # removes indirect call failures as it makes them go through regardless of type
    ("--inlining",),
    ("--inlining-optimizing",),
    ("--flatten", "--simplify-locals-notee-nostructure", "--local-cse",),
    # note that no pass we run here should add effects to a function, so it is
    # ok to run this pass and let the passes after it use the effects to
    # optimize
    ("--generate-global-effects",),
    ("--global-refining",),
    ("--gsi",),
    ("--gto",),
    ("--gufa",),
    ("--gufa-cast-all",),
    ("--gufa-optimizing",),
    ("--local-cse",),
    ("--heap2local",),
    ("--remove-unused-names", "--heap2local",),
    ("--heap-store-optimization",),
    ("--generate-stack-ir",),
    ("--licm",),
    ("--local-subtyping",),
    ("--memory-packing",),
    ("--merge-blocks",),
    ('--merge-locals',),
    # test a few monomorphization levels, and also -always
    ('--monomorphize', '--pass-arg=monomorphize-min-benefit@0'),
    ('--monomorphize', '--pass-arg=monomorphize-min-benefit@50'),
    ('--monomorphize', '--pass-arg=monomorphize-min-benefit@95'),
    ('--monomorphize-always',),
    ('--minimize-rec-groups',),
    ('--no-stack-ir',),
    ('--once-reduction',),
    ("--optimize-casts",),
    ("--optimize-instructions",),
    ("--optimize-stack-ir",),
    ("--generate-stack-ir", "--optimize-stack-ir",),
    # the full lifecycle of stack IR: generate, optimize, and write (and read)
    ("--generate-stack-ir", "--optimize-stack-ir", "--roundtrip"),
    ("--pick-load-signs",),
    ("--precompute",),
    ("--precompute-propagate",),
    ("--print",),
    ("--remove-unused-brs",),
    ("--remove-unused-nonfunction-module-elements",),
    ("--remove-unused-module-elements",),
    ("--remove-unused-names",),
    ("--remove-unused-types",),
    ("--reorder-functions",),
    ("--reorder-locals",),
    ("--reorder-types",),
    ("--flatten", "--rereloop",),
    ("--roundtrip",),
    ("--rse",),
    ("--signature-pruning",),
    ("--signature-refining",),
    ("--simplify-globals",),
    ("--simplify-globals-optimizing",),
    ("--simplify-locals",),
    ("--simplify-locals-nonesting",),
    ("--simplify-locals-nostructure",),
    ("--simplify-locals-notee",),
    ("--simplify-locals-notee-nostructure",),
    ("--ssa",),
    ("--tuple-optimization",),
    ("--type-finalizing",),
    ("--type-refining",),
    ("--type-refining-gufa",),
    ("--type-merging",),
    ("--type-ssa",),
    ("--type-unfinalizing",),
    ("--unsubtyping",),
    ("--vacuum",),
]

# TODO: Fix these passes so that they still work without --closed-world!
requires_closed_world = {("--type-refining",),
                         ("--type-refining-gufa",),
                         ("--signature-pruning",),
                         ("--signature-refining",),
                         ("--gto",),
                         ("--remove-unused-types",),
                         ("--abstract-type-refining",),
                         ("--cfp",),
                         ("--cfp-reftest",),
                         ("--reorder-types",),
                         ("--type-finalizing",),
                         ("--type-unfinalizing",),
                         ("--type-ssa",),
                         ("--type-merging",),
                         ("--unsubtyping",)}


def get_random_opts():
    flag_groups = []
    has_flatten = False

    if CLOSED_WORLD:
        usable_opt_choices = opt_choices
    else:
        usable_opt_choices = [choice
                              for choice in opt_choices
                              if choice not in requires_closed_world]

    # core opts
    while 1:
        choice = random.choice(usable_opt_choices)
        if '--flatten' in choice or '-O4' in choice:
            if has_flatten:
                print('avoiding multiple --flatten in a single command, due to exponential overhead')
                continue
            if '--enable-multivalue' in FEATURE_OPTS and '--enable-reference-types' in FEATURE_OPTS:
                print('avoiding --flatten due to multivalue + reference types not supporting it (spilling of non-nullable tuples)')
                print('TODO: Resolving https://github.com/WebAssembly/binaryen/issues/4824 may fix this')
                continue
            if '--enable-exception-handling' in FEATURE_OPTS:
                print('avoiding --flatten due to exception-handling not supporting it (requires blocks with results)')
                continue
            if '--gc' not in FEATURE_OPTS:
                print('avoiding --flatten due to GC not supporting it (spilling of non-nullable locals)')
                continue
            if INITIAL_CONTENTS and os.path.getsize(INITIAL_CONTENTS) > 2000:
                print('avoiding --flatten due using a large amount of initial contents, which may blow up')
                continue
            else:
                has_flatten = True
        if ('--rereloop' in choice or '--dfo' in choice) and \
           '--enable-exception-handling' in FEATURE_OPTS:
            print('avoiding --rereloop or --dfo due to exception-handling not supporting it')
            continue
        flag_groups.append(choice)
        if len(flag_groups) > 20 or random.random() < 0.3:
            break
    # maybe add an extra round trip
    if random.random() < 0.5:
        pos = random.randint(0, len(flag_groups))
        flag_groups = flag_groups[:pos] + [('--roundtrip',)] + flag_groups[pos:]
    ret = [flag for group in flag_groups for flag in group]
    # modifiers (if not already implied by a -O? option)
    if '-O' not in str(ret):
        if random.random() < 0.5:
            ret += ['--optimize-level=' + str(random.randint(0, 3))]
        if random.random() < 0.5:
            ret += ['--shrink-level=' + str(random.randint(0, 3))]
    # possibly converge. don't do this very often as it can be slow.
    if random.random() < 0.05:
        ret += ['--converge']
    # possibly inline all the things as much as possible. inlining that much may
    # be realistic in some cases (on GC benchmarks it is very helpful), but
    # also, inlining so much allows other optimizations to kick in, which
    # increases coverage
    # (the specific number here doesn't matter, but it is far higher than the
    # wasm limitation on function body size which is 128K)
    if random.random() < 0.5:
        ret += ['-fimfs=99999999']
    # the default for partial-inlining-ifs is 0, so also test with a realistic
    # value (the same used in j2wasm atm)
    if random.random() < 0.5:
        ret += ['-pii=4']
    # test both closed and open world
    if CLOSED_WORLD:
        ret += [CLOSED_WORLD_FLAG]
    assert ret.count('--flatten') <= 1
    return ret


# main

# list of all the flags to disable all the features. if all of these are added
# then we target the MVP.
FEATURE_DISABLE_FLAGS = run([in_bin('wasm-opt'), '--print-features', in_binaryen('test', 'hello_world.wat')] + CONSTANT_FEATURE_OPTS).replace('--enable', '--disable').strip().split('\n')
print('FEATURE_DISABLE_FLAGS:', FEATURE_DISABLE_FLAGS)

# some features depend on other features, so if a required feature is
# disabled, its dependent features need to be disabled as well.
IMPLIED_FEATURE_OPTS = {
    '--disable-reference-types': ['--disable-gc', '--disable-exception-handling', '--disable-strings'],
    '--disable-gc': ['--disable-strings', '--disable-stack-switching', '--disable-custom-descriptors'],
}

print('''
<<< fuzz_opt.py >>>
''')

if not shared.V8:
    print('The v8 shell, d8, must be in the path')
    sys.exit(1)

start_time = time.time()

if __name__ == '__main__':
    # if we are given a seed, run exactly that one testcase. otherwise,
    # run new ones until we fail
    # if we are given a seed, we can also be given a wasm file, which we use
    # instead of the randomly generating one. this can be useful for
    # reduction.
    given_wasm = None
    if len(shared.requested) >= 1:
        given_seed = int(shared.requested[0])
        print('checking a single given seed', given_seed)
        if len(shared.requested) >= 2:
            given_wasm = shared.requested[1]
            print('using given wasm file', given_wasm)
    else:
        given_seed = None
        print('checking infinite random inputs')

    init_important_initial_contents()

    seed = time.time() * os.getpid()
    raw_input_data = abspath('input.dat')
    counter = 0
    total_wasm_size = 0
    total_input_size = 0
    total_input_size_squares = 0
    while True:
        counter += 1
        if given_seed is not None:
            seed = given_seed
            given_seed_error = 0
        else:
            seed = random.randint(0, 1 << 64)
        random.seed(seed)
        input_size = random_size()
        total_input_size += input_size
        total_input_size_squares += input_size ** 2
        print('')
        mean = float(total_input_size) / counter
        mean_of_squares = float(total_input_size_squares) / counter
        stddev = math.sqrt(mean_of_squares - (mean ** 2))
        elapsed = max(0.000001, time.time() - start_time)
        print('ITERATION:', counter, 'seed:', seed, 'size:', input_size,
              '(mean:', str(mean) + ', stddev:', str(stddev) + ')',
              'speed:', counter / elapsed, 'iters/sec, ',
              total_wasm_size / counter, 'wasm_bytes/iter')
        if ignored_vm_runs:
            print(f'(ignored {ignored_vm_runs} iters, for reasons {ignored_vm_run_reasons})')
        print()
        make_random_input(input_size, raw_input_data)
        assert os.path.getsize(raw_input_data) == input_size
        # remove the generated wasm file, so that we can tell if the fuzzer
        # fails to create one
        if os.path.exists('a.wasm'):
            os.remove('a.wasm')
        # run an iteration of the fuzzer
        try:
            total_wasm_size += test_one(raw_input_data, given_wasm)
        except KeyboardInterrupt:
            print('(stopping by user request)')
            break
        except Exception as e:
            # print the exception manually, so that we can show our message at
            # the very end where it won't be missed
            ex_type, ex, tb = sys.exc_info()
            print('!')
            print('-----------------------------------------')
            print('Exception:')
            traceback.print_tb(tb)
            print('-----------------------------------------')
            print('!')
            # Default to an error code of 1, but change it for certain errors,
            # so we report them differently (useful for the reducer to keep
            # reducing the exact same error category)
            if given_seed is not None:
                given_seed_error = 1
            for arg in e.args:
                print(arg)
                if type(arg) is str:
                    if 'comparison error' in arg:
                        given_seed_error = 2

            # We want to generate a template reducer script only when there is
            # no given wasm file. That we have a given wasm file means we are no
            # longer working on the original test case but modified one, which
            # is likely to be called within wasm-reduce script itself, so
            # original.wasm and reduce.sh should not be overwritten.
            if not given_wasm:
                # We can't do this if a.wasm doesn't exist, which can be the
                # case if we failed to even generate the wasm.
                if not os.path.exists('a.wasm'):
                    print(f'''\
================================================================================
You found a bug in the fuzzer itself! It failed to generate a valid wasm file
from the random input. Please report it with

  seed: {seed}

and the exact version of Binaryen you found it on, plus the exact Python
version (hopefully deterministic random numbers will be identical).

You can run that testcase again with "fuzz_opt.py %(seed)d"

(We can't automatically reduce this testcase since we can only run the reducer
on valid wasm files.)
================================================================================
''')
                    break
                # show some useful info about filing a bug and reducing the
                # testcase (to make reduction simple, save "original.wasm" on
                # the side, so that we can autoreduce using the name "a.wasm"
                # which we use internally)
                original_wasm = abspath('original.wasm')
                shutil.copyfile('a.wasm', original_wasm)
                # write out a useful reduce.sh
                auto_init = ''
                if not shared.options.auto_initial_contents:
                    auto_init = '--no-auto-initial-contents'
                wasm_opt = in_bin('wasm-opt')
                binaryen_bin = shared.options.binaryen_bin
                temp_wasm = abspath('t.wasm')
                working_wasm = abspath('w.wasm')
                wasm_reduce = in_bin('wasm-reduce')
                reduce_sh = abspath('reduce.sh')
                features = ' '.join(FEATURE_OPTS)
                with open('reduce.sh', 'w') as f:
                    f.write(f'''\
# check the input is even a valid wasm file
echo "The following value should be 0:"
{wasm_opt} {features} {temp_wasm}
echo "  " $?

echo "The following value should be >0:"

if [ -z "$BINARYEN_FIRST_WASM" ]; then
  # run the command normally
  ./scripts/fuzz_opt.py {auto_init} --binaryen-bin {binaryen_bin} {seed} {temp_wasm} > o 2> e
else
  # BINARYEN_FIRST_WASM was provided so we should actually reduce the *second*
  # file. pass the first one in as the main file, and use the env var for the
  # second.
  BINARYEN_SECOND_WASM={temp_wasm} ./scripts/fuzz_opt.py {auto_init} --binaryen-bin {binaryen_bin} {seed} $BINARYEN_FIRST_WASM > o 2> e
fi

echo "  " $?

#
# You may want to print out part of "o" or "e", if the output matters and not
# just the return code. For example,
#
#   cat o | tail -n 10
#
# would print out the last few lines of stdout, which might be useful if that
# mentions the specific error you want. Make sure that includes the right
# details (sometimes stderr matters too), and preferably no more (less details
# allow more reduction, but raise the risk of it reducing to something you don't
# quite want).
#
# To do a "dry run" of what the reducer will do, copy the original file to the
# test file that this script will run on,
#
#   cp {original_wasm} {temp_wasm}
#
# and then run
#
#   bash {reduce_sh}
#
# You may also need to add  --timeout 5  or such if the testcase is a slow one.
#
# If the testcase handler uses a second wasm file, you may be able to reduce it
# using BINARYEN_SECOND_WASM.
#
''')

                print(f'''\
================================================================================
You found a bug! Please report it with

  seed: {seed}

and the exact version of Binaryen you found it on, plus the exact Python
version (hopefully deterministic random numbers will be identical).

You can run that testcase again with "fuzz_opt.py {seed}"

The initial wasm file used here is saved as {original_wasm}

You can reduce the testcase by running this now:

||||
vvvv


{wasm_reduce} {features} {original_wasm} '--command=bash {reduce_sh}' -t {temp_wasm} -w {working_wasm}


^^^^
||||

Make sure to verify by eye that the output says something like this:

The following value should be 0:
  0
The following value should be >0:
  1

(If it does not, then one possible issue is that the fuzzer fails to write a
valid binary. If so, you can print the output of the fuzzer's first command
(using -ttf / --translate-to-fuzz) in text form and run the reduction from that,
passing --text to the reducer. Another possible fix is to avoid re-processing
the wasm for fuzzing in each iteration, by adding
BINARYEN_TRUST_GIVEN_WASM=1 in the env.)

You can also read "{reduce_sh}" which has been filled out for you and includes
docs and suggestions.

After reduction, the reduced file will be in {working_wasm}
================================================================================
''')
                break
        if given_seed is not None:
            break

        print('\nInvocations so far:')
        for testcase_handler in testcase_handlers:
            print('  ', testcase_handler.__class__.__name__ + ':', testcase_handler.count_runs())

    if given_seed is not None:
        if not given_seed_error:
            print(f'(finished running seed {given_seed} without error)')
            sys.exit(0)
        else:
            print(f'(finished running seed {given_seed}, see error above)')
            sys.exit(given_seed_error)
