blob: 0c5abb8287dca5be0bf6c963afe66fe9f458a515 [file] [log] [blame] [edit]
#!/usr/bin/env python3
#
# Copyright 2017 WebAssembly Community Group participants
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import subprocess
from scripts.test import shared
from scripts.test import support
def test_asm2wasm():
print('[ checking asm2wasm testcases... ]\n')
for asm in shared.get_tests(shared.options.binaryen_test, ['.asm.js']):
basename = os.path.basename(asm)
for precise in [0, 1, 2]:
for opts in [1, 0]:
cmd = shared.ASM2WASM + [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 basename:
cmd += ['-g']
if 'noffi' in basename:
cmd += ['--no-legalize-javascript-ffi']
if precise and opts:
# test mem init importing
open('a.mem', 'w').write(basename)
cmd += ['--mem-init=a.mem']
if basename[0] == 'e':
cmd += ['--mem-base=1024']
if '4GB' in basename:
cmd += ['--mem-max=4294967296']
if 'i64' in basename or 'wasm-only' in basename or 'noffi' in basename:
cmd += ['--wasm-only']
print('..', basename, os.path.basename(wasm))
def do_asm2wasm_test():
actual = support.run_command(cmd)
# verify output
if not os.path.exists(wasm):
shared.fail_with_error('output .wast file %s does not exist' % wasm)
shared.fail_if_not_identical_to_file(actual, wasm)
shared.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 shared.options.interpreter:
# remove imports, spec interpreter doesn't know what to do with them
subprocess.check_call(shared.WASM_OPT + ['--remove-imports', wasm],
stdout=open('ztemp.wast', 'w'),
stderr=subprocess.PIPE)
proc = subprocess.Popen([shared.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
shared.fail_with_error('wasm interpreter error: ' + err)
shared.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']
support.run_command(cmd)
if not os.path.isfile(jsmap):
shared.fail_with_error('Debug info map not created: %s' % jsmap)
with open(jsmap, 'rb') as actual:
shared.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:
shared.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:]:
shared.fail_with_error('source map url not found in url section')
def test_asm2wasm_binary():
print('\n[ checking asm2wasm binary reading/writing... ]\n')
asmjs = os.path.join(shared.options.binaryen_test, 'hello_world.asm.js')
shared.delete_from_orbit('a.wasm')
shared.delete_from_orbit('b.wast')
support.run_command(shared.ASM2WASM + [asmjs, '-o', 'a.wasm'])
assert open('a.wasm', 'rb').read()[0] == 0, 'we emit binary by default'
support.run_command(shared.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()