diff options
-rwxr-xr-x | scripts/fuzz_opt.py | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py index 3d4663501..2bf5cd820 100755 --- a/scripts/fuzz_opt.py +++ b/scripts/fuzz_opt.py @@ -1194,19 +1194,22 @@ def get_exports(wasm, kinds): # given a wasm and a list of exports we want to keep, remove all other exports. -def filter_exports(wasm, output, keep): +# 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[:] - # some exports must always 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) + if not 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 = [{ @@ -1369,6 +1372,23 @@ class Merge(TestCaseHandler): 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() |