summaryrefslogtreecommitdiff
path: root/scripts/test
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/test')
-rwxr-xr-xscripts/test/asm2wasm.py254
-rwxr-xr-xscripts/test/binaryenjs.py88
-rwxr-xr-xscripts/test/generate_lld_tests.py106
-rwxr-xr-xscripts/test/lld.py112
-rw-r--r--scripts/test/shared.py553
-rw-r--r--scripts/test/support.py280
-rwxr-xr-xscripts/test/wasm2js.py220
7 files changed, 807 insertions, 806 deletions
diff --git a/scripts/test/asm2wasm.py b/scripts/test/asm2wasm.py
index 356d8c0f2..356a3d85c 100755
--- a/scripts/test/asm2wasm.py
+++ b/scripts/test/asm2wasm.py
@@ -25,137 +25,137 @@ from .shared import (
def test_asm2wasm():
- print('[ checking asm2wasm testcases... ]\n')
-
- for asm in tests:
- if not asm.endswith('.asm.js'):
- continue
- for precise in [0, 1, 2]:
- for opts in [1, 0]:
- cmd = ASM2WASM + [os.path.join(options.binaryen_test, asm)]
- if 'threads' in asm:
- cmd += ['--enable-threads']
- wasm = asm.replace('.asm.js', '.fromasm')
- if not precise:
- cmd += ['--trap-mode=allow', '--ignore-implicit-traps']
- wasm += '.imprecise'
- elif precise == 2:
- cmd += ['--trap-mode=clamp']
- wasm += '.clamp'
- if not opts:
- wasm += '.no-opts'
- if precise:
- cmd += ['-O0'] # test that -O0 does nothing
- else:
- cmd += ['-O']
- if 'debugInfo' in asm:
- cmd += ['-g']
- if 'noffi' in asm:
- cmd += ['--no-legalize-javascript-ffi']
- if precise and opts:
- # test mem init importing
- open('a.mem', 'w').write(asm)
- cmd += ['--mem-init=a.mem']
- if asm[0] == 'e':
- cmd += ['--mem-base=1024']
- if '4GB' in asm:
- cmd += ['--mem-max=4294967296']
- if 'i64' in asm or 'wasm-only' in asm or 'noffi' in asm:
- cmd += ['--wasm-only']
- wasm = os.path.join(options.binaryen_test, wasm)
- print('..', asm, wasm)
-
- def do_asm2wasm_test():
- actual = run_command(cmd)
-
- # verify output
- if not os.path.exists(wasm):
- fail_with_error('output .wast file %s does not exist' % wasm)
- fail_if_not_identical_to_file(actual, wasm)
-
- binary_format_check(wasm, verify_final_result=False)
-
- # test both normally and with pass debug (so each inter-pass state
- # is validated)
- old_pass_debug = os.environ.get('BINARYEN_PASS_DEBUG')
- try:
- os.environ['BINARYEN_PASS_DEBUG'] = '1'
- print("With BINARYEN_PASS_DEBUG=1:")
- do_asm2wasm_test()
- del os.environ['BINARYEN_PASS_DEBUG']
- print("With BINARYEN_PASS_DEBUG disabled:")
- do_asm2wasm_test()
- finally:
- if old_pass_debug is not None:
- os.environ['BINARYEN_PASS_DEBUG'] = old_pass_debug
- else:
- if 'BINARYEN_PASS_DEBUG' in os.environ:
- del os.environ['BINARYEN_PASS_DEBUG']
-
- # verify in wasm
- if options.interpreter:
- # remove imports, spec interpreter doesn't know what to do with them
- subprocess.check_call(WASM_OPT + ['--remove-imports', wasm],
- stdout=open('ztemp.wast', 'w'),
- stderr=subprocess.PIPE)
- proc = subprocess.Popen([options.interpreter, 'ztemp.wast'],
- stderr=subprocess.PIPE)
- out, err = proc.communicate()
- if proc.returncode != 0:
- try: # to parse the error
- reported = err.split(':')[1]
- start, end = reported.split('-')
- start_line, start_col = map(int, start.split('.'))
- lines = open('ztemp.wast').read().split('\n')
- print()
- print('=' * 80)
- print(lines[start_line - 1])
- print((' ' * (start_col - 1)) + '^')
- print((' ' * (start_col - 2)) + '/_\\')
- print('=' * 80)
- print(err)
- except Exception:
- # failed to pretty-print
- fail_with_error('wasm interpreter error: ' + err)
- fail_with_error('wasm interpreter error')
-
- # verify debug info
- if 'debugInfo' in asm:
- jsmap = 'a.wasm.map'
- cmd += ['--source-map', jsmap,
- '--source-map-url', 'http://example.org/' + jsmap,
- '-o', 'a.wasm']
- run_command(cmd)
- if not os.path.isfile(jsmap):
- fail_with_error('Debug info map not created: %s' % jsmap)
- with open(jsmap, 'rb') as actual:
- fail_if_not_identical_to_file(actual.read(), wasm + '.map')
- with open('a.wasm', 'rb') as binary:
- url_section_name = bytes([16]) + bytes('sourceMappingURL', 'utf-8')
- url = 'http://example.org/' + jsmap
- assert len(url) < 256, 'name too long'
- url_section_contents = bytes([len(url)]) + bytes(url, 'utf-8')
- print(url_section_name)
- binary_contents = binary.read()
- if url_section_name not in binary_contents:
- fail_with_error('source map url section not found in binary')
- url_section_index = binary_contents.index(url_section_name)
- if url_section_contents not in binary_contents[url_section_index:]:
- fail_with_error('source map url not found in url section')
+ print('[ checking asm2wasm testcases... ]\n')
+
+ for asm in tests:
+ if not asm.endswith('.asm.js'):
+ continue
+ for precise in [0, 1, 2]:
+ for opts in [1, 0]:
+ cmd = ASM2WASM + [os.path.join(options.binaryen_test, asm)]
+ if 'threads' in asm:
+ cmd += ['--enable-threads']
+ wasm = asm.replace('.asm.js', '.fromasm')
+ if not precise:
+ cmd += ['--trap-mode=allow', '--ignore-implicit-traps']
+ wasm += '.imprecise'
+ elif precise == 2:
+ cmd += ['--trap-mode=clamp']
+ wasm += '.clamp'
+ if not opts:
+ wasm += '.no-opts'
+ if precise:
+ cmd += ['-O0'] # test that -O0 does nothing
+ else:
+ cmd += ['-O']
+ if 'debugInfo' in asm:
+ cmd += ['-g']
+ if 'noffi' in asm:
+ cmd += ['--no-legalize-javascript-ffi']
+ if precise and opts:
+ # test mem init importing
+ open('a.mem', 'w').write(asm)
+ cmd += ['--mem-init=a.mem']
+ if asm[0] == 'e':
+ cmd += ['--mem-base=1024']
+ if '4GB' in asm:
+ cmd += ['--mem-max=4294967296']
+ if 'i64' in asm or 'wasm-only' in asm or 'noffi' in asm:
+ cmd += ['--wasm-only']
+ wasm = os.path.join(options.binaryen_test, wasm)
+ print('..', asm, wasm)
+
+ def do_asm2wasm_test():
+ actual = run_command(cmd)
+
+ # verify output
+ if not os.path.exists(wasm):
+ fail_with_error('output .wast file %s does not exist' % wasm)
+ fail_if_not_identical_to_file(actual, wasm)
+
+ binary_format_check(wasm, verify_final_result=False)
+
+ # test both normally and with pass debug (so each inter-pass state
+ # is validated)
+ old_pass_debug = os.environ.get('BINARYEN_PASS_DEBUG')
+ try:
+ os.environ['BINARYEN_PASS_DEBUG'] = '1'
+ print("With BINARYEN_PASS_DEBUG=1:")
+ do_asm2wasm_test()
+ del os.environ['BINARYEN_PASS_DEBUG']
+ print("With BINARYEN_PASS_DEBUG disabled:")
+ do_asm2wasm_test()
+ finally:
+ if old_pass_debug is not None:
+ os.environ['BINARYEN_PASS_DEBUG'] = old_pass_debug
+ else:
+ if 'BINARYEN_PASS_DEBUG' in os.environ:
+ del os.environ['BINARYEN_PASS_DEBUG']
+
+ # verify in wasm
+ if options.interpreter:
+ # remove imports, spec interpreter doesn't know what to do with them
+ subprocess.check_call(WASM_OPT + ['--remove-imports', wasm],
+ stdout=open('ztemp.wast', 'w'),
+ stderr=subprocess.PIPE)
+ proc = subprocess.Popen([options.interpreter, 'ztemp.wast'],
+ stderr=subprocess.PIPE)
+ out, err = proc.communicate()
+ if proc.returncode != 0:
+ try: # to parse the error
+ reported = err.split(':')[1]
+ start, end = reported.split('-')
+ start_line, start_col = map(int, start.split('.'))
+ lines = open('ztemp.wast').read().split('\n')
+ print()
+ print('=' * 80)
+ print(lines[start_line - 1])
+ print((' ' * (start_col - 1)) + '^')
+ print((' ' * (start_col - 2)) + '/_\\')
+ print('=' * 80)
+ print(err)
+ except Exception:
+ # failed to pretty-print
+ fail_with_error('wasm interpreter error: ' + err)
+ fail_with_error('wasm interpreter error')
+
+ # verify debug info
+ if 'debugInfo' in asm:
+ jsmap = 'a.wasm.map'
+ cmd += ['--source-map', jsmap,
+ '--source-map-url', 'http://example.org/' + jsmap,
+ '-o', 'a.wasm']
+ run_command(cmd)
+ if not os.path.isfile(jsmap):
+ fail_with_error('Debug info map not created: %s' % jsmap)
+ with open(jsmap, 'rb') as actual:
+ fail_if_not_identical_to_file(actual.read(), wasm + '.map')
+ with open('a.wasm', 'rb') as binary:
+ url_section_name = bytes([16]) + bytes('sourceMappingURL', 'utf-8')
+ url = 'http://example.org/' + jsmap
+ assert len(url) < 256, 'name too long'
+ url_section_contents = bytes([len(url)]) + bytes(url, 'utf-8')
+ print(url_section_name)
+ binary_contents = binary.read()
+ if url_section_name not in binary_contents:
+ fail_with_error('source map url section not found in binary')
+ url_section_index = binary_contents.index(url_section_name)
+ if url_section_contents not in binary_contents[url_section_index:]:
+ fail_with_error('source map url not found in url section')
def test_asm2wasm_binary():
- print('\n[ checking asm2wasm binary reading/writing... ]\n')
+ print('\n[ checking asm2wasm binary reading/writing... ]\n')
- asmjs = os.path.join(options.binaryen_test, 'hello_world.asm.js')
- delete_from_orbit('a.wasm')
- delete_from_orbit('b.wast')
- run_command(ASM2WASM + [asmjs, '-o', 'a.wasm'])
- assert open('a.wasm', 'rb').read()[0] == 0, 'we emit binary by default'
- run_command(ASM2WASM + [asmjs, '-o', 'b.wast', '-S'])
- assert open('b.wast', 'rb').read()[0] != 0, 'we emit text with -S'
+ asmjs = os.path.join(options.binaryen_test, 'hello_world.asm.js')
+ delete_from_orbit('a.wasm')
+ delete_from_orbit('b.wast')
+ run_command(ASM2WASM + [asmjs, '-o', 'a.wasm'])
+ assert open('a.wasm', 'rb').read()[0] == 0, 'we emit binary by default'
+ run_command(ASM2WASM + [asmjs, '-o', 'b.wast', '-S'])
+ assert open('b.wast', 'rb').read()[0] != 0, 'we emit text with -S'
if __name__ == '__main__':
- test_asm2wasm()
- test_asm2wasm_binary()
+ test_asm2wasm()
+ test_asm2wasm_binary()
diff --git a/scripts/test/binaryenjs.py b/scripts/test/binaryenjs.py
index f701f25c1..a102c2ae4 100755
--- a/scripts/test/binaryenjs.py
+++ b/scripts/test/binaryenjs.py
@@ -22,56 +22,56 @@ from .shared import BINARYEN_JS, MOZJS, NODEJS, options, fail
def test_binaryen_js():
- if not (MOZJS or NODEJS):
- print('no vm to run binaryen.js tests')
- return
+ if not (MOZJS or NODEJS):
+ print('no vm to run binaryen.js tests')
+ return
- node_has_wasm = NODEJS and node_has_webassembly(NODEJS)
+ node_has_wasm = NODEJS and node_has_webassembly(NODEJS)
- if not os.path.exists(BINARYEN_JS):
- print('no binaryen.js build to test')
- return
+ if not os.path.exists(BINARYEN_JS):
+ print('no binaryen.js build to test')
+ return
- print('\n[ checking binaryen.js testcases... ]\n')
+ print('\n[ checking binaryen.js testcases... ]\n')
- for s in sorted(os.listdir(os.path.join(options.binaryen_test, 'binaryen.js'))):
- if not s.endswith('.js'):
- continue
- print(s)
- f = open('a.js', 'w')
- # avoid stdout/stderr ordering issues in some js shells - use just stdout
- f.write('''
- console.warn = function(x) { console.log(x) };
- ''')
- binaryen_js = open(BINARYEN_JS).read()
- f.write(binaryen_js)
- if NODEJS:
- f.write(node_test_glue())
- test_path = os.path.join(options.binaryen_test, 'binaryen.js', s)
- test_src = open(test_path).read()
- f.write(test_src)
- f.close()
+ for s in sorted(os.listdir(os.path.join(options.binaryen_test, 'binaryen.js'))):
+ if not s.endswith('.js'):
+ continue
+ print(s)
+ f = open('a.js', 'w')
+ # avoid stdout/stderr ordering issues in some js shells - use just stdout
+ f.write('''
+ console.warn = function(x) { console.log(x) };
+ ''')
+ binaryen_js = open(BINARYEN_JS).read()
+ f.write(binaryen_js)
+ if NODEJS:
+ f.write(node_test_glue())
+ test_path = os.path.join(options.binaryen_test, 'binaryen.js', s)
+ test_src = open(test_path).read()
+ f.write(test_src)
+ f.close()
- def test(engine):
- cmd = [engine, 'a.js']
- if 'fatal' not in s:
- out = run_command(cmd, stderr=subprocess.STDOUT)
- else:
- # expect an error - the specific error code will depend on the vm
- out = run_command(cmd, stderr=subprocess.STDOUT, expected_status=None)
- expected = open(os.path.join(options.binaryen_test, 'binaryen.js', s + '.txt')).read()
- if expected not in out:
- fail(out, expected)
+ def test(engine):
+ cmd = [engine, 'a.js']
+ if 'fatal' not in s:
+ out = run_command(cmd, stderr=subprocess.STDOUT)
+ else:
+ # expect an error - the specific error code will depend on the vm
+ out = run_command(cmd, stderr=subprocess.STDOUT, expected_status=None)
+ expected = open(os.path.join(options.binaryen_test, 'binaryen.js', s + '.txt')).read()
+ if expected not in out:
+ fail(out, expected)
- # run in all possible shells
- if MOZJS:
- test(MOZJS)
- if NODEJS:
- if node_has_wasm or 'WebAssembly.' not in test_src:
- test(NODEJS)
- else:
- print('Skipping ' + test_path + ' because WebAssembly might not be supported')
+ # run in all possible shells
+ if MOZJS:
+ test(MOZJS)
+ if NODEJS:
+ if node_has_wasm or 'WebAssembly.' not in test_src:
+ test(NODEJS)
+ else:
+ print('Skipping ' + test_path + ' because WebAssembly might not be supported')
if __name__ == "__main__":
- test_binaryen_js()
+ test_binaryen_js()
diff --git a/scripts/test/generate_lld_tests.py b/scripts/test/generate_lld_tests.py
index 9447fe973..b5cb6b140 100755
--- a/scripts/test/generate_lld_tests.py
+++ b/scripts/test/generate_lld_tests.py
@@ -23,69 +23,69 @@ import shared
def files_with_extensions(path, extensions):
- for file in sorted(os.listdir(path)):
- ext = os.path.splitext(file)[1]
- if ext in extensions:
- yield file, ext
+ for file in sorted(os.listdir(path)):
+ ext = os.path.splitext(file)[1]
+ if ext in extensions:
+ yield file, ext
def generate_wast_files(llvm_bin, emscripten_root):
- print('\n[ building wast files from C sources... ]\n')
+ print('\n[ building wast files from C sources... ]\n')
- lld_path = os.path.join(shared.options.binaryen_test, 'lld')
- for src_file, ext in files_with_extensions(lld_path, ['.c', '.cpp']):
- print('..', src_file)
- obj_file = src_file.replace(ext, '.o')
+ lld_path = os.path.join(shared.options.binaryen_test, 'lld')
+ for src_file, ext in files_with_extensions(lld_path, ['.c', '.cpp']):
+ print('..', src_file)
+ obj_file = src_file.replace(ext, '.o')
- src_path = os.path.join(lld_path, src_file)
- obj_path = os.path.join(lld_path, obj_file)
+ src_path = os.path.join(lld_path, src_file)
+ obj_path = os.path.join(lld_path, obj_file)
- wasm_file = src_file.replace(ext, '.wasm')
- wast_file = src_file.replace(ext, '.wast')
+ wasm_file = src_file.replace(ext, '.wasm')
+ wast_file = src_file.replace(ext, '.wast')
- obj_path = os.path.join(lld_path, obj_file)
- wasm_path = os.path.join(lld_path, wasm_file)
- wast_path = os.path.join(lld_path, wast_file)
- is_shared = 'shared' in src_file
+ obj_path = os.path.join(lld_path, obj_file)
+ wasm_path = os.path.join(lld_path, wasm_file)
+ wast_path = os.path.join(lld_path, wast_file)
+ is_shared = 'shared' in src_file
- compile_cmd = [
- os.path.join(llvm_bin, 'clang'), src_path, '-o', obj_path,
- '--target=wasm32-unknown-unknown-wasm',
- '-c',
- '-nostdinc',
- '-Xclang', '-nobuiltininc',
- '-Xclang', '-nostdsysteminc',
- '-Xclang', '-I%s/system/include' % emscripten_root,
- '-O1',
- ]
+ compile_cmd = [
+ os.path.join(llvm_bin, 'clang'), src_path, '-o', obj_path,
+ '--target=wasm32-unknown-unknown-wasm',
+ '-c',
+ '-nostdinc',
+ '-Xclang', '-nobuiltininc',
+ '-Xclang', '-nostdsysteminc',
+ '-Xclang', '-I%s/system/include' % emscripten_root,
+ '-O1',
+ ]
- link_cmd = [
- os.path.join(llvm_bin, 'wasm-ld'), '-flavor', 'wasm',
- '-z', '-stack-size=1048576',
- obj_path, '-o', wasm_path,
- '--allow-undefined',
- '--export', '__wasm_call_ctors',
- '--global-base=568',
- ]
- if is_shared:
- compile_cmd.append('-fPIC')
- compile_cmd.append('-fvisibility=default')
- link_cmd.append('-shared')
- else:
- link_cmd.append('--entry=main')
+ link_cmd = [
+ os.path.join(llvm_bin, 'wasm-ld'), '-flavor', 'wasm',
+ '-z', '-stack-size=1048576',
+ obj_path, '-o', wasm_path,
+ '--allow-undefined',
+ '--export', '__wasm_call_ctors',
+ '--global-base=568',
+ ]
+ if is_shared:
+ compile_cmd.append('-fPIC')
+ compile_cmd.append('-fvisibility=default')
+ link_cmd.append('-shared')
+ else:
+ link_cmd.append('--entry=main')
- try:
- run_command(compile_cmd)
- run_command(link_cmd)
- run_command(shared.WASM_DIS + [wasm_path, '-o', wast_path])
- finally:
- # Don't need the .o or .wasm files, don't leave them around
- shared.delete_from_orbit(obj_path)
- shared.delete_from_orbit(wasm_path)
+ try:
+ run_command(compile_cmd)
+ run_command(link_cmd)
+ run_command(shared.WASM_DIS + [wasm_path, '-o', wast_path])
+ finally:
+ # Don't need the .o or .wasm files, don't leave them around
+ shared.delete_from_orbit(obj_path)
+ shared.delete_from_orbit(wasm_path)
if __name__ == '__main__':
- if len(shared.options.positional_args) != 2:
- print('Usage: generate_lld_tests.py [llvm/bin/dir] [path/to/emscripten]')
- sys.exit(1)
- generate_wast_files(*shared.options.positional_args)
+ if len(shared.options.positional_args) != 2:
+ print('Usage: generate_lld_tests.py [llvm/bin/dir] [path/to/emscripten]')
+ sys.exit(1)
+ generate_wast_files(*shared.options.positional_args)
diff --git a/scripts/test/lld.py b/scripts/test/lld.py
index 1a553506f..4aafd9549 100755
--- a/scripts/test/lld.py
+++ b/scripts/test/lld.py
@@ -22,72 +22,72 @@ from .shared import (
def args_for_finalize(filename):
- if 'safe_stack' in filename:
- return ['--check-stack-overflow', '--global-base=568']
- elif 'shared' in filename:
- return ['--side-module']
- else:
- return ['--global-base=568']
+ if 'safe_stack' in filename:
+ return ['--check-stack-overflow', '--global-base=568']
+ elif 'shared' in filename:
+ return ['--side-module']
+ else:
+ return ['--global-base=568']
def test_wasm_emscripten_finalize():
- print('\n[ checking wasm-emscripten-finalize testcases... ]\n')
+ print('\n[ checking wasm-emscripten-finalize testcases... ]\n')
- for wast_path in files_with_pattern(options.binaryen_test, 'lld', '*.wast'):
- print('..', wast_path)
- is_passive = '.passive.' in wast_path
- mem_file = wast_path + '.mem'
- extension_arg_map = {
- '.out': [],
- }
- if not is_passive:
- extension_arg_map.update({
- '.mem.out': ['--separate-data-segments', mem_file],
- })
- for ext, ext_args in extension_arg_map.items():
- expected_file = wast_path + ext
- if ext != '.out' and not os.path.exists(expected_file):
- continue
+ for wast_path in files_with_pattern(options.binaryen_test, 'lld', '*.wast'):
+ print('..', wast_path)
+ is_passive = '.passive.' in wast_path
+ mem_file = wast_path + '.mem'
+ extension_arg_map = {
+ '.out': [],
+ }
+ if not is_passive:
+ extension_arg_map.update({
+ '.mem.out': ['--separate-data-segments', mem_file],
+ })
+ for ext, ext_args in extension_arg_map.items():
+ expected_file = wast_path + ext
+ if ext != '.out' and not os.path.exists(expected_file):
+ continue
- cmd = WASM_EMSCRIPTEN_FINALIZE + [wast_path, '-S'] + ext_args
- cmd += args_for_finalize(os.path.basename(wast_path))
- actual = run_command(cmd)
+ cmd = WASM_EMSCRIPTEN_FINALIZE + [wast_path, '-S'] + ext_args
+ cmd += args_for_finalize(os.path.basename(wast_path))
+ actual = run_command(cmd)
- if not os.path.exists(expected_file):
- print(actual)
- fail_with_error('output ' + expected_file + ' does not exist')
- fail_if_not_identical_to_file(actual, expected_file)
- if ext == '.mem.out':
- with open(mem_file) as mf:
- mem = mf.read()
- fail_if_not_identical_to_file(mem, wast_path + '.mem.mem')
- os.remove(mem_file)
+ if not os.path.exists(expected_file):
+ print(actual)
+ fail_with_error('output ' + expected_file + ' does not exist')
+ fail_if_not_identical_to_file(actual, expected_file)
+ if ext == '.mem.out':
+ with open(mem_file) as mf:
+ mem = mf.read()
+ fail_if_not_identical_to_file(mem, wast_path + '.mem.mem')
+ os.remove(mem_file)
def update_lld_tests():
- print('\n[ updatring wasm-emscripten-finalize testcases... ]\n')
+ print('\n[ updatring wasm-emscripten-finalize testcases... ]\n')
- for wast_path in files_with_pattern(options.binaryen_test, 'lld', '*.wast'):
- print('..', wast_path)
- is_passive = '.passive.' in wast_path
- mem_file = wast_path + '.mem'
- extension_arg_map = {
- '.out': [],
- }
- if not is_passive:
- extension_arg_map.update({
- '.mem.out': ['--separate-data-segments', mem_file + '.mem'],
- })
- for ext, ext_args in extension_arg_map.items():
- out_path = wast_path + ext
- if ext != '.out' and not os.path.exists(out_path):
- continue
- cmd = WASM_EMSCRIPTEN_FINALIZE + [wast_path, '-S'] + ext_args
- cmd += args_for_finalize(os.path.basename(wast_path))
- actual = run_command(cmd)
- with open(out_path, 'w') as o:
- o.write(actual)
+ for wast_path in files_with_pattern(options.binaryen_test, 'lld', '*.wast'):
+ print('..', wast_path)
+ is_passive = '.passive.' in wast_path
+ mem_file = wast_path + '.mem'
+ extension_arg_map = {
+ '.out': [],
+ }
+ if not is_passive:
+ extension_arg_map.update({
+ '.mem.out': ['--separate-data-segments', mem_file + '.mem'],
+ })
+ for ext, ext_args in extension_arg_map.items():
+ out_path = wast_path + ext
+ if ext != '.out' and not os.path.exists(out_path):
+ continue
+ cmd = WASM_EMSCRIPTEN_FINALIZE + [wast_path, '-S'] + ext_args
+ cmd += args_for_finalize(os.path.basename(wast_path))
+ actual = run_command(cmd)
+ with open(out_path, 'w') as o:
+ o.write(actual)
if __name__ == '__main__':
- test_wasm_emscripten_finalize()
+ test_wasm_emscripten_finalize()
diff --git a/scripts/test/shared.py b/scripts/test/shared.py
index a712f5176..2440077a8 100644
--- a/scripts/test/shared.py
+++ b/scripts/test/shared.py
@@ -24,61 +24,61 @@ import sys
def parse_args(args):
- usage_str = ("usage: 'python check.py [options]'\n\n"
- "Runs the Binaryen test suite.")
- parser = argparse.ArgumentParser(description=usage_str)
- parser.add_argument(
- '--torture', dest='torture', action='store_true', default=True,
- help='Chooses whether to run the torture testcases. Default: true.')
- parser.add_argument(
- '--no-torture', dest='torture', action='store_false',
- help='Disables running the torture testcases.')
- parser.add_argument(
- '--abort-on-first-failure', dest='abort_on_first_failure',
- action='store_true', default=True,
- help=('Specifies whether to halt test suite execution on first test error.'
- ' Default: true.'))
- parser.add_argument(
- '--no-abort-on-first-failure', dest='abort_on_first_failure',
- action='store_false',
- help=('If set, the whole test suite will run to completion independent of'
- ' earlier errors.'))
-
- parser.add_argument(
- '--interpreter', dest='interpreter', default='',
- help='Specifies the wasm interpreter executable to run tests on.')
- parser.add_argument(
- '--binaryen-bin', dest='binaryen_bin', default='',
- help=('Specifies a path to where the built Binaryen executables reside at.'
- ' Default: bin/ of current directory (i.e. assume an in-tree build).'
- ' If not specified, the environment variable BINARYEN_ROOT= can also'
- ' be used to adjust this.'))
- parser.add_argument(
- '--binaryen-root', dest='binaryen_root', default='',
- help=('Specifies a path to the root of the Binaryen repository tree.'
- ' Default: the directory where this file check.py resides.'))
- parser.add_argument(
- '--valgrind', dest='valgrind', default='',
- help=('Specifies a path to Valgrind tool, which will be used to validate'
- ' execution if specified. (Pass --valgrind=valgrind to search in'
- ' PATH)'))
- parser.add_argument(
- '--valgrind-full-leak-check', dest='valgrind_full_leak_check',
- action='store_true', default=False,
- help=('If specified, all unfreed (but still referenced) pointers at the'
- ' end of execution are considered memory leaks. Default: disabled.'))
- parser.add_argument(
- '--spec-test', action='append', nargs='*', default=[], dest='spec_tests',
- help='Names specific spec tests to run.')
- parser.add_argument(
- 'positional_args', metavar='TEST_SUITE', nargs='*',
- help=('Names specific test suites to run. Use --list-suites to see a '
- 'list of all test suites'))
- parser.add_argument(
- '--list-suites', action='store_true',
- help='List the test suites that can be run.')
-
- return parser.parse_args(args)
+ usage_str = ("usage: 'python check.py [options]'\n\n"
+ "Runs the Binaryen test suite.")
+ parser = argparse.ArgumentParser(description=usage_str)
+ parser.add_argument(
+ '--torture', dest='torture', action='store_true', default=True,
+ help='Chooses whether to run the torture testcases. Default: true.')
+ parser.add_argument(
+ '--no-torture', dest='torture', action='store_false',
+ help='Disables running the torture testcases.')
+ parser.add_argument(
+ '--abort-on-first-failure', dest='abort_on_first_failure',
+ action='store_true', default=True,
+ help=('Specifies whether to halt test suite execution on first test error.'
+ ' Default: true.'))
+ parser.add_argument(
+ '--no-abort-on-first-failure', dest='abort_on_first_failure',
+ action='store_false',
+ help=('If set, the whole test suite will run to completion independent of'
+ ' earlier errors.'))
+
+ parser.add_argument(
+ '--interpreter', dest='interpreter', default='',
+ help='Specifies the wasm interpreter executable to run tests on.')
+ parser.add_argument(
+ '--binaryen-bin', dest='binaryen_bin', default='',
+ help=('Specifies a path to where the built Binaryen executables reside at.'
+ ' Default: bin/ of current directory (i.e. assume an in-tree build).'
+ ' If not specified, the environment variable BINARYEN_ROOT= can also'
+ ' be used to adjust this.'))
+ parser.add_argument(
+ '--binaryen-root', dest='binaryen_root', default='',
+ help=('Specifies a path to the root of the Binaryen repository tree.'
+ ' Default: the directory where this file check.py resides.'))
+ parser.add_argument(
+ '--valgrind', dest='valgrind', default='',
+ help=('Specifies a path to Valgrind tool, which will be used to validate'
+ ' execution if specified. (Pass --valgrind=valgrind to search in'
+ ' PATH)'))
+ parser.add_argument(
+ '--valgrind-full-leak-check', dest='valgrind_full_leak_check',
+ action='store_true', default=False,
+ help=('If specified, all unfreed (but still referenced) pointers at the'
+ ' end of execution are considered memory leaks. Default: disabled.'))
+ parser.add_argument(
+ '--spec-test', action='append', nargs='*', default=[], dest='spec_tests',
+ help='Names specific spec tests to run.')
+ parser.add_argument(
+ 'positional_args', metavar='TEST_SUITE', nargs='*',
+ help=('Names specific test suites to run. Use --list-suites to see a '
+ 'list of all test suites'))
+ parser.add_argument(
+ '--list-suites', action='store_true',
+ help='List the test suites that can be run.')
+
+ return parser.parse_args(args)
options = parse_args(sys.argv[1:])
@@ -89,23 +89,23 @@ warnings = []
def warn(text):
- global warnings
- warnings.append(text)
- print('warning:', text, file=sys.stderr)
+ global warnings
+ warnings.append(text)
+ print('warning:', text, file=sys.stderr)
# setup
# Locate Binaryen build artifacts directory (bin/ by default)
if not options.binaryen_bin:
- if os.environ.get('BINARYEN_ROOT'):
- if os.path.isdir(os.path.join(os.environ.get('BINARYEN_ROOT'), 'bin')):
- options.binaryen_bin = os.path.join(
- os.environ.get('BINARYEN_ROOT'), 'bin')
+ if os.environ.get('BINARYEN_ROOT'):
+ if os.path.isdir(os.path.join(os.environ.get('BINARYEN_ROOT'), 'bin')):
+ options.binaryen_bin = os.path.join(
+ os.environ.get('BINARYEN_ROOT'), 'bin')
+ else:
+ options.binaryen_bin = os.environ.get('BINARYEN_ROOT')
else:
- options.binaryen_bin = os.environ.get('BINARYEN_ROOT')
- else:
- options.binaryen_bin = 'bin'
+ options.binaryen_bin = 'bin'
options.binaryen_bin = os.path.normpath(os.path.abspath(options.binaryen_bin))
@@ -115,12 +115,12 @@ os.environ['BINARYEN_ROOT'] = os.path.dirname(options.binaryen_bin)
wasm_dis_filenames = ['wasm-dis', 'wasm-dis.exe']
if not any(os.path.isfile(os.path.join(options.binaryen_bin, f))
for f in wasm_dis_filenames):
- warn('Binaryen not found (or has not been successfully built to bin/ ?')
+ warn('Binaryen not found (or has not been successfully built to bin/ ?')
# Locate Binaryen source directory if not specified.
if not options.binaryen_root:
- path_parts = os.path.abspath(__file__).split(os.path.sep)
- options.binaryen_root = os.path.sep.join(path_parts[:-3])
+ path_parts = os.path.abspath(__file__).split(os.path.sep)
+ options.binaryen_root = os.path.sep.join(path_parts[:-3])
options.binaryen_test = os.path.join(options.binaryen_root, 'test')
@@ -128,30 +128,29 @@ options.binaryen_test = os.path.join(options.binaryen_root, 'test')
# Finds the given executable 'program' in PATH.
# Operates like the Unix tool 'which'.
def which(program):
- def is_exe(fpath):
- return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
- fpath, fname = os.path.split(program)
- if fpath:
- if is_exe(program):
- return program
- else:
- for path in os.environ["PATH"].split(os.pathsep):
- path = path.strip('"')
- exe_file = os.path.join(path, program)
- if is_exe(exe_file):
- return exe_file
- if '.' not in fname:
- if is_exe(exe_file + '.exe'):
- return exe_file + '.exe'
- if is_exe(exe_file + '.cmd'):
- return exe_file + '.cmd'
- if is_exe(exe_file + '.bat'):
- return exe_file + '.bat'
+ def is_exe(fpath):
+ return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+ fpath, fname = os.path.split(program)
+ if fpath:
+ if is_exe(program):
+ return program
+ else:
+ for path in os.environ["PATH"].split(os.pathsep):
+ path = path.strip('"')
+ exe_file = os.path.join(path, program)
+ if is_exe(exe_file):
+ return exe_file
+ if '.' not in fname:
+ if is_exe(exe_file + '.exe'):
+ return exe_file + '.exe'
+ if is_exe(exe_file + '.cmd'):
+ return exe_file + '.cmd'
+ if is_exe(exe_file + '.bat'):
+ return exe_file + '.bat'
WATERFALL_BUILD_DIR = os.path.join(options.binaryen_test, 'wasm-install')
-BIN_DIR = os.path.abspath(os.path.join(
- WATERFALL_BUILD_DIR, 'wasm-install', 'bin'))
+BIN_DIR = os.path.abspath(os.path.join(WATERFALL_BUILD_DIR, 'wasm-install', 'bin'))
NATIVECC = (os.environ.get('CC') or which('mingw32-gcc') or
which('gcc') or which('clang'))
@@ -178,53 +177,53 @@ BINARYEN_JS = os.path.join(options.binaryen_root, 'out', 'binaryen.js')
def wrap_with_valgrind(cmd):
- # Exit code 97 is arbitrary, used to easily detect when an error occurs that
- # is detected by Valgrind.
- valgrind = [options.valgrind, '--quiet', '--error-exitcode=97']
- if options.valgrind_full_leak_check:
- valgrind += ['--leak-check=full', '--show-leak-kinds=all']
- return valgrind + cmd
+ # Exit code 97 is arbitrary, used to easily detect when an error occurs that
+ # is detected by Valgrind.
+ valgrind = [options.valgrind, '--quiet', '--error-exitcode=97']
+ if options.valgrind_full_leak_check:
+ valgrind += ['--leak-check=full', '--show-leak-kinds=all']
+ return valgrind + cmd
if options.valgrind:
- WASM_OPT = wrap_with_valgrind(WASM_OPT)
- WASM_AS = wrap_with_valgrind(WASM_AS)
- WASM_DIS = wrap_with_valgrind(WASM_DIS)
- ASM2WASM = wrap_with_valgrind(ASM2WASM)
- WASM_SHELL = wrap_with_valgrind(WASM_SHELL)
+ WASM_OPT = wrap_with_valgrind(WASM_OPT)
+ WASM_AS = wrap_with_valgrind(WASM_AS)
+ WASM_DIS = wrap_with_valgrind(WASM_DIS)
+ ASM2WASM = wrap_with_valgrind(ASM2WASM)
+ WASM_SHELL = wrap_with_valgrind(WASM_SHELL)
def in_binaryen(*args):
- __rootpath__ = os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
- return os.path.join(__rootpath__, *args)
+ __rootpath__ = os.path.abspath(os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
+ return os.path.join(__rootpath__, *args)
os.environ['BINARYEN'] = in_binaryen()
def get_platform():
- return {'linux': 'linux',
- 'linux2': 'linux',
- 'darwin': 'mac',
- 'win32': 'windows',
- 'cygwin': 'windows'}[sys.platform]
+ return {'linux': 'linux',
+ 'linux2': 'linux',
+ 'darwin': 'mac',
+ 'win32': 'windows',
+ 'cygwin': 'windows'}[sys.platform]
def has_shell_timeout():
- return get_platform() != 'windows' and os.system('timeout 1s pwd') == 0
+ return get_platform() != 'windows' and os.system('timeout 1s pwd') == 0
# Default options to pass to v8. These enable all features.
V8_OPTS = [
- '--experimental-wasm-eh',
- '--experimental-wasm-mv',
- '--experimental-wasm-sat-f2i-conversions',
- '--experimental-wasm-se',
- '--experimental-wasm-threads',
- '--experimental-wasm-simd',
- '--experimental-wasm-anyref',
- '--experimental-wasm-bulk-memory',
- '--experimental-wasm-return-call'
+ '--experimental-wasm-eh',
+ '--experimental-wasm-mv',
+ '--experimental-wasm-sat-f2i-conversions',
+ '--experimental-wasm-se',
+ '--experimental-wasm-threads',
+ '--experimental-wasm-simd',
+ '--experimental-wasm-anyref',
+ '--experimental-wasm-bulk-memory',
+ '--experimental-wasm-return-call'
]
has_vanilla_llvm = False
@@ -232,232 +231,234 @@ has_vanilla_llvm = False
# external tools
try:
- if NODEJS is not None:
- subprocess.check_call(
- [NODEJS, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if NODEJS is not None:
+ subprocess.check_call([NODEJS, '--version'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
except (OSError, subprocess.CalledProcessError):
- NODEJS = None
+ NODEJS = None
if NODEJS is None:
- warn('no node found (did not check proper js form)')
+ warn('no node found (did not check proper js form)')
try:
- if MOZJS is not None:
- subprocess.check_call(
- [MOZJS, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if MOZJS is not None:
+ subprocess.check_call([MOZJS, '--version'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
except (OSError, subprocess.CalledProcessError):
- MOZJS = None
+ MOZJS = None
if MOZJS is None:
- warn('no mozjs found (did not check native wasm support nor asm.js'
- ' validation)')
+ warn('no mozjs found (did not check native wasm support nor asm.js'
+ ' validation)')
try:
- if EMCC is not None:
- subprocess.check_call(
- [EMCC, '--version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ if EMCC is not None:
+ subprocess.check_call([EMCC, '--version'],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
except (OSError, subprocess.CalledProcessError):
- EMCC = None
+ EMCC = None
if EMCC is None:
- warn('no emcc found (did not check non-vanilla emscripten/binaryen'
- ' integration)')
+ warn('no emcc found (did not check non-vanilla emscripten/binaryen'
+ ' integration)')
has_vanilla_emcc = False
try:
- subprocess.check_call(
- [os.path.join(options.binaryen_test, 'emscripten', 'emcc'), '--version'],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- has_vanilla_emcc = True
+ subprocess.check_call(
+ [os.path.join(options.binaryen_test, 'emscripten', 'emcc'), '--version'],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ has_vanilla_emcc = True
except (OSError, subprocess.CalledProcessError):
- pass
+ pass
# utilities
# removes a file if it exists, using any and all ways of doing so
def delete_from_orbit(filename):
- try:
- os.unlink(filename)
- except OSError:
- pass
- if not os.path.exists(filename):
- return
- try:
- shutil.rmtree(filename, ignore_errors=True)
- except OSError:
- pass
- if not os.path.exists(filename):
- return
- try:
- import stat
- os.chmod(filename, os.stat(filename).st_mode | stat.S_IWRITE)
-
- def remove_readonly_and_try_again(func, path, exc_info):
- if not (os.stat(path).st_mode & stat.S_IWRITE):
- os.chmod(path, os.stat(path).st_mode | stat.S_IWRITE)
- func(path)
- else:
- raise
- shutil.rmtree(filename, onerror=remove_readonly_and_try_again)
- except OSError:
- pass
+ try:
+ os.unlink(filename)
+ except OSError:
+ pass
+ if not os.path.exists(filename):
+ return
+ try:
+ shutil.rmtree(filename, ignore_errors=True)
+ except OSError:
+ pass
+ if not os.path.exists(filename):
+ return
+ try:
+ import stat
+ os.chmod(filename, os.stat(filename).st_mode | stat.S_IWRITE)
+
+ def remove_readonly_and_try_again(func, path, exc_info):
+ if not (os.stat(path).st_mode & stat.S_IWRITE):
+ os.chmod(path, os.stat(path).st_mode | stat.S_IWRITE)
+ func(path)
+ else:
+ raise
+ shutil.rmtree(filename, onerror=remove_readonly_and_try_again)
+ except OSError:
+ pass
# This is a workaround for https://bugs.python.org/issue9400
class Py2CalledProcessError(subprocess.CalledProcessError):
- def __init__(self, returncode, cmd, output=None, stderr=None):
- super(Exception, self).__init__(returncode, cmd, output, stderr)
- self.returncode = returncode
- self.cmd = cmd
- self.output = output
- self.stderr = stderr
+ def __init__(self, returncode, cmd, output=None, stderr=None):
+ super(Exception, self).__init__(returncode, cmd, output, stderr)
+ self.returncode = returncode
+ self.cmd = cmd
+ self.output = output
+ self.stderr = stderr
def run_process(cmd, check=True, input=None, capture_output=False, *args, **kw):
- if input and type(input) == str:
- input = bytes(input, 'utf-8')
- if capture_output:
- kw['stdout'] = subprocess.PIPE
- kw['stderr'] = subprocess.PIPE
- ret = subprocess.run(cmd, check=check, input=input, *args, **kw)
- if ret.stdout is not None:
- ret.stdout = ret.stdout.decode('utf-8')
- if ret.stderr is not None:
- ret.stderr = ret.stderr.decode('utf-8')
- return ret
+ if input and type(input) == str:
+ input = bytes(input, 'utf-8')
+ if capture_output:
+ kw['stdout'] = subprocess.PIPE
+ kw['stderr'] = subprocess.PIPE
+ ret = subprocess.run(cmd, check=check, input=input, *args, **kw)
+ if ret.stdout is not None:
+ ret.stdout = ret.stdout.decode('utf-8')
+ if ret.stderr is not None:
+ ret.stderr = ret.stderr.decode('utf-8')
+ return ret
def fail_with_error(msg):
- global num_failures
- try:
- num_failures += 1
- raise Exception(msg)
- except Exception as e:
- print(str(e))
- if options.abort_on_first_failure:
- raise
+ global num_failures
+ try:
+ num_failures += 1
+ raise Exception(msg)
+ except Exception as e:
+ print(str(e))
+ if options.abort_on_first_failure:
+ raise
def fail(actual, expected, fromfile='expected'):
- diff_lines = difflib.unified_diff(
- expected.split('\n'), actual.split('\n'),
- fromfile=fromfile, tofile='actual')
- diff_str = ''.join([a.rstrip() + '\n' for a in diff_lines])[:]
- fail_with_error("incorrect output, diff:\n\n%s" % diff_str)
+ diff_lines = difflib.unified_diff(
+ expected.split('\n'), actual.split('\n'),
+ fromfile=fromfile, tofile='actual')
+ diff_str = ''.join([a.rstrip() + '\n' for a in diff_lines])[:]
+ fail_with_error("incorrect output, diff:\n\n%s" % diff_str)
def fail_if_not_identical(actual, expected, fromfile='expected'):
- if expected != actual:
- fail(actual, expected, fromfile=fromfile)
+ if expected != actual:
+ fail(actual, expected, fromfile=fromfile)
def fail_if_not_contained(actual, expected):
- if expected not in actual:
- fail(actual, expected)
+ if expected not in actual:
+ fail(actual, expected)
def fail_if_not_identical_to_file(actual, expected_file):
- binary = expected_file.endswith(".wasm") or type(actual) == bytes
- with open(expected_file, 'rb' if binary else 'r') as f:
- fail_if_not_identical(actual, f.read(), fromfile=expected_file)
+ binary = expected_file.endswith(".wasm") or type(actual) == bytes
+ with open(expected_file, 'rb' if binary else 'r') as f:
+ fail_if_not_identical(actual, f.read(), fromfile=expected_file)
if len(requested) == 0:
- tests = sorted(os.listdir(os.path.join(options.binaryen_test)))
+ tests = sorted(os.listdir(os.path.join(options.binaryen_test)))
else:
- tests = requested[:]
+ tests = requested[:]
if not options.interpreter:
- warn('no interpreter provided (did not test spec interpreter validation)')
+ warn('no interpreter provided (did not test spec interpreter validation)')
if not has_vanilla_emcc:
- warn('no functional emcc submodule found')
+ warn('no functional emcc submodule found')
# check utilities
def validate_binary(wasm):
- if V8:
- cmd = [V8] + V8_OPTS + [in_binaryen('scripts', 'validation_shell.js'), '--', wasm]
- print(' ', ' '.join(cmd))
- subprocess.check_call(cmd, stdout=subprocess.PIPE)
- else:
- print('(skipping v8 binary validation)')
+ if V8:
+ cmd = [V8] + V8_OPTS + [in_binaryen('scripts', 'validation_shell.js'), '--', wasm]
+ print(' ', ' '.join(cmd))
+ subprocess.check_call(cmd, stdout=subprocess.PIPE)
+ else:
+ print('(skipping v8 binary validation)')
def binary_format_check(wast, verify_final_result=True, wasm_as_args=['-g'],
binary_suffix='.fromBinary', original_wast=None):
- # checks we can convert the wast to binary and back
-
- print(' (binary format check)')
- cmd = WASM_AS + [wast, '-o', 'a.wasm', '-all'] + wasm_as_args
- print(' ', ' '.join(cmd))
- if os.path.exists('a.wasm'):
- os.unlink('a.wasm')
- subprocess.check_call(cmd, stdout=subprocess.PIPE)
- assert os.path.exists('a.wasm')
-
- # make sure it is a valid wasm, using a real wasm VM
- if os.path.basename(original_wast or wast) not in [
- 'atomics.wast', # https://bugs.chromium.org/p/v8/issues/detail?id=9425
- 'simd.wast', # https://bugs.chromium.org/p/v8/issues/detail?id=8460
- ]:
- validate_binary('a.wasm')
-
- cmd = WASM_DIS + ['a.wasm', '-o', 'ab.wast']
- print(' ', ' '.join(cmd))
- if os.path.exists('ab.wast'):
- os.unlink('ab.wast')
- subprocess.check_call(cmd, stdout=subprocess.PIPE)
- assert os.path.exists('ab.wast')
-
- # make sure it is a valid wast
- cmd = WASM_OPT + ['ab.wast', '-all']
- print(' ', ' '.join(cmd))
- subprocess.check_call(cmd, stdout=subprocess.PIPE)
-
- if verify_final_result:
- actual = open('ab.wast').read()
- fail_if_not_identical_to_file(actual, wast + binary_suffix)
-
- return 'ab.wast'
+ # checks we can convert the wast to binary and back
+
+ print(' (binary format check)')
+ cmd = WASM_AS + [wast, '-o', 'a.wasm', '-all'] + wasm_as_args
+ print(' ', ' '.join(cmd))
+ if os.path.exists('a.wasm'):
+ os.unlink('a.wasm')
+ subprocess.check_call(cmd, stdout=subprocess.PIPE)
+ assert os.path.exists('a.wasm')
+
+ # make sure it is a valid wasm, using a real wasm VM
+ if os.path.basename(original_wast or wast) not in [
+ 'atomics.wast', # https://bugs.chromium.org/p/v8/issues/detail?id=9425
+ 'simd.wast', # https://bugs.chromium.org/p/v8/issues/detail?id=8460
+ ]:
+ validate_binary('a.wasm')
+
+ cmd = WASM_DIS + ['a.wasm', '-o', 'ab.wast']
+ print(' ', ' '.join(cmd))
+ if os.path.exists('ab.wast'):
+ os.unlink('ab.wast')
+ subprocess.check_call(cmd, stdout=subprocess.PIPE)
+ assert os.path.exists('ab.wast')
+
+ # make sure it is a valid wast
+ cmd = WASM_OPT + ['ab.wast', '-all']
+ print(' ', ' '.join(cmd))
+ subprocess.check_call(cmd, stdout=subprocess.PIPE)
+
+ if verify_final_result:
+ actual = open('ab.wast').read()
+ fail_if_not_identical_to_file(actual, wast + binary_suffix)
+
+ return 'ab.wast'
def minify_check(wast, verify_final_result=True):
- # checks we can parse minified output
-
- print(' (minify check)')
- cmd = WASM_OPT + [wast, '--print-minified', '-all']
- print(' ', ' '.join(cmd))
- subprocess.check_call(cmd, stdout=open('a.wast', 'w'), stderr=subprocess.PIPE)
- assert os.path.exists('a.wast')
- subprocess.check_call(
- WASM_OPT + ['a.wast', '--print-minified', '-all'],
- stdout=open('b.wast', 'w'), stderr=subprocess.PIPE)
- assert os.path.exists('b.wast')
- if verify_final_result:
- expected = open('a.wast').read()
- actual = open('b.wast').read()
- if actual != expected:
- fail(actual, expected)
- if os.path.exists('a.wast'):
- os.unlink('a.wast')
- if os.path.exists('b.wast'):
- os.unlink('b.wast')
+ # checks we can parse minified output
+
+ print(' (minify check)')
+ cmd = WASM_OPT + [wast, '--print-minified', '-all']
+ print(' ', ' '.join(cmd))
+ subprocess.check_call(cmd, stdout=open('a.wast', 'w'), stderr=subprocess.PIPE)
+ assert os.path.exists('a.wast')
+ subprocess.check_call(WASM_OPT + ['a.wast', '--print-minified', '-all'],
+ stdout=open('b.wast', 'w'), stderr=subprocess.PIPE)
+ assert os.path.exists('b.wast')
+ if verify_final_result:
+ expected = open('a.wast').read()
+ actual = open('b.wast').read()
+ if actual != expected:
+ fail(actual, expected)
+ if os.path.exists('a.wast'):
+ os.unlink('a.wast')
+ if os.path.exists('b.wast'):
+ os.unlink('b.wast')
def files_with_pattern(*path_pattern):
- return sorted(glob.glob(os.path.join(*path_pattern)))
+ return sorted(glob.glob(os.path.join(*path_pattern)))
# run a check with BINARYEN_PASS_DEBUG set, to do full validation
def with_pass_debug(check):
- old_pass_debug = os.environ.get('BINARYEN_PASS_DEBUG')
- try:
- os.environ['BINARYEN_PASS_DEBUG'] = '1'
- check()
- finally:
- if old_pass_debug is not None:
- os.environ['BINARYEN_PASS_DEBUG'] = old_pass_debug
- else:
- if 'BINARYEN_PASS_DEBUG' in os.environ:
- del os.environ['BINARYEN_PASS_DEBUG']
+ old_pass_debug = os.environ.get('BINARYEN_PASS_DEBUG')
+ try:
+ os.environ['BINARYEN_PASS_DEBUG'] = '1'
+ check()
+ finally:
+ if old_pass_debug is not None:
+ os.environ['BINARYEN_PASS_DEBUG'] = old_pass_debug
+ else:
+ if 'BINARYEN_PASS_DEBUG' in os.environ:
+ del os.environ['BINARYEN_PASS_DEBUG']
diff --git a/scripts/test/support.py b/scripts/test/support.py
index 90bc531eb..8f48a7af9 100644
--- a/scripts/test/support.py
+++ b/scripts/test/support.py
@@ -21,178 +21,178 @@ import tempfile
def _open_archive(tarfile, tmp_dir):
- with tempfile.TemporaryFile(mode='w+') as f:
- try:
- subprocess.check_call(['tar', '-xvf', tarfile], cwd=tmp_dir, stdout=f)
- except Exception:
- f.seek(0)
- sys.stderr.write(f.read())
- raise
- return os.listdir(tmp_dir)
+ with tempfile.TemporaryFile(mode='w+') as f:
+ try:
+ subprocess.check_call(['tar', '-xvf', tarfile], cwd=tmp_dir, stdout=f)
+ except Exception:
+ f.seek(0)
+ sys.stderr.write(f.read())
+ raise
+ return os.listdir(tmp_dir)
def _files_same(dir1, dir2, basenames):
- diff = filecmp.cmpfiles(dir1, dir2, basenames)
- return 0 == len(diff[1] + diff[2])
+ diff = filecmp.cmpfiles(dir1, dir2, basenames)
+ return 0 == len(diff[1] + diff[2])
def _dirs_same(dir1, dir2, basenames):
- for d in basenames:
- left = os.path.join(dir1, d)
- right = os.path.join(dir2, d)
- if not (os.path.isdir(left) and os.path.isdir(right)):
- return False
- diff = filecmp.dircmp(right, right)
- if 0 != len(diff.left_only + diff.right_only + diff.diff_files +
- diff.common_funny + diff.funny_files):
- return False
- return True
+ for d in basenames:
+ left = os.path.join(dir1, d)
+ right = os.path.join(dir2, d)
+ if not (os.path.isdir(left) and os.path.isdir(right)):
+ return False
+ diff = filecmp.dircmp(right, right)
+ if 0 != len(diff.left_only + diff.right_only + diff.diff_files +
+ diff.common_funny + diff.funny_files):
+ return False
+ return True
def _move_files(dirfrom, dirto, basenames):
- for f in basenames:
- from_file = os.path.join(dirfrom, f)
- to_file = os.path.join(dirto, f)
- if os.path.isfile(to_file):
- os.path.remove(to_file)
- shutil.move(from_file, to_file)
+ for f in basenames:
+ from_file = os.path.join(dirfrom, f)
+ to_file = os.path.join(dirto, f)
+ if os.path.isfile(to_file):
+ os.path.remove(to_file)
+ shutil.move(from_file, to_file)
def _move_dirs(dirfrom, dirto, basenames):
for d in basenames:
- from_dir = os.path.join(dirfrom, d)
- to_dir = os.path.join(dirto, d)
- if os.path.isdir(to_dir):
- shutil.rmtree(to_dir)
- shutil.move(from_dir, to_dir)
+ from_dir = os.path.join(dirfrom, d)
+ to_dir = os.path.join(dirto, d)
+ if os.path.isdir(to_dir):
+ shutil.rmtree(to_dir)
+ shutil.move(from_dir, to_dir)
def untar(tarfile, outdir):
- """Returns True if untar content differs from pre-existing outdir content."""
- tmpdir = tempfile.mkdtemp()
- try:
- untared = _open_archive(tarfile, tmpdir)
- files = [f for f in untared if os.path.isfile(os.path.join(tmpdir, f))]
- dirs = [d for d in untared if os.path.isdir(os.path.join(tmpdir, d))]
- assert len(files) + len(dirs) == len(untared), 'Only files and directories'
- if _files_same(tmpdir, outdir, files) and _dirs_same(tmpdir, outdir, dirs):
- # Nothing new or different in the tarfile.
- return False
- # Some or all of the files / directories are new.
- _move_files(tmpdir, outdir, files)
- _move_dirs(tmpdir, outdir, dirs)
- return True
- finally:
- if os.path.isdir(tmpdir):
- shutil.rmtree(tmpdir)
+ """Returns True if untar content differs from pre-existing outdir content."""
+ tmpdir = tempfile.mkdtemp()
+ try:
+ untared = _open_archive(tarfile, tmpdir)
+ files = [f for f in untared if os.path.isfile(os.path.join(tmpdir, f))]
+ dirs = [d for d in untared if os.path.isdir(os.path.join(tmpdir, d))]
+ assert len(files) + len(dirs) == len(untared), 'Only files and directories'
+ if _files_same(tmpdir, outdir, files) and _dirs_same(tmpdir, outdir, dirs):
+ # Nothing new or different in the tarfile.
+ return False
+ # Some or all of the files / directories are new.
+ _move_files(tmpdir, outdir, files)
+ _move_dirs(tmpdir, outdir, dirs)
+ return True
+ finally:
+ if os.path.isdir(tmpdir):
+ shutil.rmtree(tmpdir)
def split_wast(wastFile):
- # if it's a binary, leave it as is, we can't split it
- wast = None
- if not wastFile.endswith('.wasm'):
- try:
- wast = open(wastFile, 'r').read()
- except Exception:
- pass
-
- if not wast:
- return ((open(wastFile, 'rb').read(), []),)
-
- # .wast files can contain multiple modules, and assertions for each one.
- # this splits out a wast into [(module, assertions), ..]
- # we ignore module invalidity tests here.
- ret = []
-
- def to_end(j):
- depth = 1
- while depth > 0 and j < len(wast):
- if wast[j] == '"':
- while 1:
- j = wast.find('"', j + 1)
- if wast[j - 1] == '\\':
+ # if it's a binary, leave it as is, we can't split it
+ wast = None
+ if not wastFile.endswith('.wasm'):
+ try:
+ wast = open(wastFile, 'r').read()
+ except Exception:
+ pass
+
+ if not wast:
+ return ((open(wastFile, 'rb').read(), []),)
+
+ # .wast files can contain multiple modules, and assertions for each one.
+ # this splits out a wast into [(module, assertions), ..]
+ # we ignore module invalidity tests here.
+ ret = []
+
+ def to_end(j):
+ depth = 1
+ while depth > 0 and j < len(wast):
+ if wast[j] == '"':
+ while 1:
+ j = wast.find('"', j + 1)
+ if wast[j - 1] == '\\':
+ continue
+ break
+ assert j > 0
+ elif wast[j] == '(':
+ depth += 1
+ elif wast[j] == ')':
+ depth -= 1
+ elif wast[j] == ';' and wast[j + 1] == ';':
+ j = wast.find('\n', j)
+ j += 1
+ return j
+
+ i = 0
+ while i >= 0:
+ start = wast.find('(', i)
+ if start >= 0 and wast[start + 1] == ';':
+ # block comment
+ i = wast.find(';)', start + 2)
+ assert i > 0, wast[start:]
+ i += 2
+ continue
+ skip = wast.find(';', i)
+ if skip >= 0 and skip < start and skip + 1 < len(wast):
+ if wast[skip + 1] == ';':
+ i = wast.find('\n', i) + 1
+ continue
+ if start < 0:
+ break
+ i = to_end(start + 1)
+ chunk = wast[start:i]
+ if chunk.startswith('(module'):
+ ret += [(chunk, [])]
+ elif chunk.startswith('(assert_invalid'):
continue
- break
- assert j > 0
- elif wast[j] == '(':
- depth += 1
- elif wast[j] == ')':
- depth -= 1
- elif wast[j] == ';' and wast[j + 1] == ';':
- j = wast.find('\n', j)
- j += 1
- return j
-
- i = 0
- while i >= 0:
- start = wast.find('(', i)
- if start >= 0 and wast[start + 1] == ';':
- # block comment
- i = wast.find(';)', start + 2)
- assert i > 0, wast[start:]
- i += 2
- continue
- skip = wast.find(';', i)
- if skip >= 0 and skip < start and skip + 1 < len(wast):
- if wast[skip + 1] == ';':
- i = wast.find('\n', i) + 1
- continue
- if start < 0:
- break
- i = to_end(start + 1)
- chunk = wast[start:i]
- if chunk.startswith('(module'):
- ret += [(chunk, [])]
- elif chunk.startswith('(assert_invalid'):
- continue
- elif chunk.startswith(('(assert', '(invoke')):
- ret[-1][1].append(chunk)
- return ret
+ elif chunk.startswith(('(assert', '(invoke')):
+ ret[-1][1].append(chunk)
+ return ret
# write a split wast from split_wast. the wast may be binary if the original
# file was binary
def write_wast(filename, wast, asserts=[]):
- if type(wast) == bytes:
- assert not asserts
- with open(filename, 'wb') as o:
- o.write(wast)
- else:
- with open(filename, 'w') as o:
- o.write(wast + '\n'.join(asserts))
+ if type(wast) == bytes:
+ assert not asserts
+ with open(filename, 'wb') as o:
+ o.write(wast)
+ else:
+ with open(filename, 'w') as o:
+ o.write(wast + '\n'.join(asserts))
def run_command(cmd, expected_status=0, stderr=None,
expected_err=None, err_contains=False, err_ignore=None):
- if expected_err is not None:
- assert stderr == subprocess.PIPE or stderr is None,\
- "Can't redirect stderr if using expected_err"
- stderr = subprocess.PIPE
- print('executing: ', ' '.join(cmd))
- proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=stderr, universal_newlines=True)
- out, err = proc.communicate()
- code = proc.returncode
- if expected_status is not None and code != expected_status:
- raise Exception(('run_command failed (%s)' % code, out + str(err or '')))
- if expected_err is not None:
- if err_ignore is not None:
- err = "\n".join([line for line in err.split('\n') if err_ignore not in line])
- err_correct = expected_err in err if err_contains else expected_err == err
- if not err_correct:
- raise Exception(('run_command unexpected stderr',
- "expected '%s', actual '%s'" % (expected_err, err)))
- return out
+ if expected_err is not None:
+ assert stderr == subprocess.PIPE or stderr is None,\
+ "Can't redirect stderr if using expected_err"
+ stderr = subprocess.PIPE
+ print('executing: ', ' '.join(cmd))
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=stderr, universal_newlines=True)
+ out, err = proc.communicate()
+ code = proc.returncode
+ if expected_status is not None and code != expected_status:
+ raise Exception(('run_command failed (%s)' % code, out + str(err or '')))
+ if expected_err is not None:
+ if err_ignore is not None:
+ err = "\n".join([line for line in err.split('\n') if err_ignore not in line])
+ err_correct = expected_err in err if err_contains else expected_err == err
+ if not err_correct:
+ raise Exception(('run_command unexpected stderr',
+ "expected '%s', actual '%s'" % (expected_err, err)))
+ return out
def node_has_webassembly(cmd):
- cmd = [cmd, '-e', 'process.stdout.write(typeof WebAssembly)']
- return run_command(cmd) == 'object'
+ cmd = [cmd, '-e', 'process.stdout.write(typeof WebAssembly)']
+ return run_command(cmd) == 'object'
def node_test_glue():
- # running concatenated files (a.js) in node interferes with module loading
- # because the concatenated file expects a 'var Binaryen' but binaryen.js
- # assigned to module.exports. this is correct behavior but tests then need
- # a workaround:
- return ('if (typeof module === "object" && typeof exports === "object")\n'
- ' Binaryen = module.exports;\n')
+ # running concatenated files (a.js) in node interferes with module loading
+ # because the concatenated file expects a 'var Binaryen' but binaryen.js
+ # assigned to module.exports. this is correct behavior but tests then need
+ # a workaround:
+ return ('if (typeof module === "object" && typeof exports === "object")\n'
+ ' Binaryen = module.exports;\n')
diff --git a/scripts/test/wasm2js.py b/scripts/test/wasm2js.py
index 8c8f9a840..39ba946fe 100755
--- a/scripts/test/wasm2js.py
+++ b/scripts/test/wasm2js.py
@@ -36,155 +36,155 @@ wasm2js_blacklist = ['empty_imported_table.wast']
def test_wasm2js_output():
- for opt in (0, 1):
- for wasm in tests + spec_tests + extra_wasm2js_tests:
- if not wasm.endswith('.wast'):
- continue
- basename = os.path.basename(wasm)
- if basename in wasm2js_blacklist:
- continue
+ for opt in (0, 1):
+ for wasm in tests + spec_tests + extra_wasm2js_tests:
+ if not wasm.endswith('.wast'):
+ continue
+ basename = os.path.basename(wasm)
+ if basename in wasm2js_blacklist:
+ continue
- asm = basename.replace('.wast', '.2asm.js')
- expected_file = os.path.join(wasm2js_dir, asm)
- if opt:
- expected_file += '.opt'
+ asm = basename.replace('.wast', '.2asm.js')
+ expected_file = os.path.join(wasm2js_dir, asm)
+ if opt:
+ expected_file += '.opt'
- if not os.path.exists(expected_file):
- continue
+ if not os.path.exists(expected_file):
+ continue
- print('..', wasm)
+ print('..', wasm)
- t = os.path.join(options.binaryen_test, wasm)
+ t = os.path.join(options.binaryen_test, wasm)
- all_out = []
+ all_out = []
- for module, asserts in split_wast(t):
- write_wast('split.wast', module, asserts)
+ for module, asserts in split_wast(t):
+ write_wast('split.wast', module, asserts)
- cmd = WASM2JS + ['split.wast']
- if opt:
- cmd += ['-O']
- if 'emscripten' in wasm:
- cmd += ['--emscripten']
- out = run_command(cmd)
- all_out.append(out)
+ cmd = WASM2JS + ['split.wast']
+ if opt:
+ cmd += ['-O']
+ if 'emscripten' in wasm:
+ cmd += ['--emscripten']
+ out = run_command(cmd)
+ all_out.append(out)
- if not NODEJS and not MOZJS:
- print('No JS interpreters. Skipping spec tests.')
- continue
+ if not NODEJS and not MOZJS:
+ print('No JS interpreters. Skipping spec tests.')
+ continue
- open('a.2asm.mjs', 'w').write(out)
+ open('a.2asm.mjs', 'w').write(out)
- cmd += ['--allow-asserts']
- out = run_command(cmd)
- # also verify it passes pass-debug verifications
- with_pass_debug(lambda: run_command(cmd))
+ cmd += ['--allow-asserts']
+ out = run_command(cmd)
+ # also verify it passes pass-debug verifications
+ with_pass_debug(lambda: run_command(cmd))
- open('a.2asm.asserts.mjs', 'w').write(out)
+ open('a.2asm.asserts.mjs', 'w').write(out)
- # verify asm.js is valid js, note that we're using --experimental-modules
- # to enable ESM syntax and we're also passing a custom loader to handle the
- # `spectest` and `env` modules in our tests.
- if NODEJS:
- node = [NODEJS, '--experimental-modules', '--loader', './scripts/test/node-esm-loader.mjs']
- cmd = node[:]
- cmd.append('a.2asm.mjs')
- out = run_command(cmd)
- fail_if_not_identical(out, '')
- cmd = node[:]
- cmd.append('a.2asm.asserts.mjs')
- out = run_command(cmd, expected_err='', err_ignore='The ESM module loader is experimental')
- fail_if_not_identical(out, '')
+ # verify asm.js is valid js, note that we're using --experimental-modules
+ # to enable ESM syntax and we're also passing a custom loader to handle the
+ # `spectest` and `env` modules in our tests.
+ if NODEJS:
+ node = [NODEJS, '--experimental-modules', '--loader', './scripts/test/node-esm-loader.mjs']
+ cmd = node[:]
+ cmd.append('a.2asm.mjs')
+ out = run_command(cmd)
+ fail_if_not_identical(out, '')
+ cmd = node[:]
+ cmd.append('a.2asm.asserts.mjs')
+ out = run_command(cmd, expected_err='', err_ignore='The ESM module loader is experimental')
+ fail_if_not_identical(out, '')
- fail_if_not_identical_to_file(''.join(all_out), expected_file)
+ fail_if_not_identical_to_file(''.join(all_out), expected_file)
def test_asserts_output():
- for wasm in assert_tests:
- print('..', wasm)
+ for wasm in assert_tests:
+ print('..', wasm)
- asserts = os.path.basename(wasm).replace('.wast.asserts', '.asserts.js')
- traps = os.path.basename(wasm).replace('.wast.asserts', '.traps.js')
- asserts_expected_file = os.path.join(options.binaryen_test, asserts)
- traps_expected_file = os.path.join(options.binaryen_test, traps)
+ asserts = os.path.basename(wasm).replace('.wast.asserts', '.asserts.js')
+ traps = os.path.basename(wasm).replace('.wast.asserts', '.traps.js')
+ asserts_expected_file = os.path.join(options.binaryen_test, asserts)
+ traps_expected_file = os.path.join(options.binaryen_test, traps)
- wasm = os.path.join(wasm2js_dir, wasm)
- cmd = WASM2JS + [wasm, '--allow-asserts']
- out = run_command(cmd)
- fail_if_not_identical_to_file(out, asserts_expected_file)
+ wasm = os.path.join(wasm2js_dir, wasm)
+ cmd = WASM2JS + [wasm, '--allow-asserts']
+ out = run_command(cmd)
+ fail_if_not_identical_to_file(out, asserts_expected_file)
- cmd += ['--pedantic']
- out = run_command(cmd)
- fail_if_not_identical_to_file(out, traps_expected_file)
+ cmd += ['--pedantic']
+ out = run_command(cmd)
+ fail_if_not_identical_to_file(out, traps_expected_file)
def test_wasm2js():
- print('\n[ checking wasm2js testcases... ]\n')
- test_wasm2js_output()
- test_asserts_output()
+ print('\n[ checking wasm2js testcases... ]\n')
+ test_wasm2js_output()
+ test_asserts_output()
def update_wasm2js_tests():
- print('\n[ checking wasm2js ]\n')
+ print('\n[ checking wasm2js ]\n')
- for opt in (0, 1):
- for wasm in tests + spec_tests + extra_wasm2js_tests:
- if not wasm.endswith('.wast'):
- continue
+ for opt in (0, 1):
+ for wasm in tests + spec_tests + extra_wasm2js_tests:
+ if not wasm.endswith('.wast'):
+ continue
- if os.path.basename(wasm) in wasm2js_blacklist:
- continue
+ if os.path.basename(wasm) in wasm2js_blacklist:
+ continue
- asm = os.path.basename(wasm).replace('.wast', '.2asm.js')
- expected_file = os.path.join(wasm2js_dir, asm)
- if opt:
- expected_file += '.opt'
+ asm = os.path.basename(wasm).replace('.wast', '.2asm.js')
+ expected_file = os.path.join(wasm2js_dir, asm)
+ if opt:
+ expected_file += '.opt'
- # we run wasm2js on tests and spec tests only if the output
- # exists - only some work so far. the tests in extra are in
- # the test/wasm2js dir and so are specific to wasm2js, and
- # we run all of those.
- if wasm not in extra_wasm2js_tests and not os.path.exists(expected_file):
- continue
+ # we run wasm2js on tests and spec tests only if the output
+ # exists - only some work so far. the tests in extra are in
+ # the test/wasm2js dir and so are specific to wasm2js, and
+ # we run all of those.
+ if wasm not in extra_wasm2js_tests and not os.path.exists(expected_file):
+ continue
- print('..', wasm)
+ print('..', wasm)
- t = os.path.join(options.binaryen_test, wasm)
+ t = os.path.join(options.binaryen_test, wasm)
- all_out = []
+ all_out = []
- for module, asserts in split_wast(t):
- write_wast('split.wast', module, asserts)
+ for module, asserts in split_wast(t):
+ write_wast('split.wast', module, asserts)
- cmd = WASM2JS + ['split.wast']
- if opt:
- cmd += ['-O']
- if 'emscripten' in wasm:
- cmd += ['--emscripten']
- out = run_command(cmd)
- all_out.append(out)
+ cmd = WASM2JS + ['split.wast']
+ if opt:
+ cmd += ['-O']
+ if 'emscripten' in wasm:
+ cmd += ['--emscripten']
+ out = run_command(cmd)
+ all_out.append(out)
- with open(expected_file, 'w') as o:
- o.write(''.join(all_out))
+ with open(expected_file, 'w') as o:
+ o.write(''.join(all_out))
- for wasm in assert_tests:
- print('..', wasm)
+ for wasm in assert_tests:
+ print('..', wasm)
- asserts = os.path.basename(wasm).replace('.wast.asserts', '.asserts.js')
- traps = os.path.basename(wasm).replace('.wast.asserts', '.traps.js')
- asserts_expected_file = os.path.join('test', asserts)
- traps_expected_file = os.path.join('test', traps)
+ asserts = os.path.basename(wasm).replace('.wast.asserts', '.asserts.js')
+ traps = os.path.basename(wasm).replace('.wast.asserts', '.traps.js')
+ asserts_expected_file = os.path.join('test', asserts)
+ traps_expected_file = os.path.join('test', traps)
- cmd = WASM2JS + [os.path.join(wasm2js_dir, wasm), '--allow-asserts']
- out = run_command(cmd)
- with open(asserts_expected_file, 'w') as o:
- o.write(out)
+ cmd = WASM2JS + [os.path.join(wasm2js_dir, wasm), '--allow-asserts']
+ out = run_command(cmd)
+ with open(asserts_expected_file, 'w') as o:
+ o.write(out)
- cmd += ['--pedantic']
- out = run_command(cmd)
- with open(traps_expected_file, 'w') as o:
- o.write(out)
+ cmd += ['--pedantic']
+ out = run_command(cmd)
+ with open(traps_expected_file, 'w') as o:
+ o.write(out)
if __name__ == "__main__":
- test_wasm2js()
+ test_wasm2js()