#!/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',
    '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',
            '--fuzz-against-js',
            '--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)
