blob: 7e0e3278c096b66cd4911541a5e5722df8233144 [file] [log] [blame]
#!/usr/bin/env python
# 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 support import run_command
from shared import (
ASM2WASM, WASM_OPT, binary_format_check, delete_from_orbit,
fail, fail_with_error, fail_if_not_identical, options, tests
)
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)]
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', 'wb').write(asm)
cmd += ['--mem-init=a.mem']
if asm[0] == 'e':
cmd += ['--mem-base=1024']
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)
expected = open(wasm, 'rb').read()
if actual != expected:
fail(actual, expected)
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(wasm + '.map', 'rb') as expected:
with open(jsmap, 'rb') as actual:
fail_if_not_identical(actual.read(), expected.read())
with open('a.wasm', 'rb') as binary:
url_section_name = bytearray([16]) + bytearray('sourceMappingURL')
url = 'http://example.org/' + jsmap
assert len(url) < 256, 'name too long'
url_section_contents = bytearray([len(url)]) + bytearray(url)
print url_section_name
binary_contents = bytearray(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'
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()