Skip to content

Share trap mode between asm2wasm and s2wasm #1168

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 54 commits into from
Oct 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
9fea05f
Extract Asm2WasmBuilder::TrapMode to shared FloatTrapMode
jgravelle-google Aug 24, 2017
2877cfd
Extract makeTrappingI32Binary
jgravelle-google Aug 24, 2017
9a51e46
Extract makeTrappingI64Binary
jgravelle-google Aug 24, 2017
625b49b
Extract asm2wasm test script into scripts/test/asm2wasm.py
jgravelle-google Aug 24, 2017
3860a7b
Simplify callsites with an arg struct
jgravelle-google Aug 24, 2017
1717c5a
Combine func adding across i32 and i64
jgravelle-google Aug 24, 2017
6a8fd32
Support f32-to-int in asm2wasm
jgravelle-google Aug 29, 2017
64fcbf6
Add BinaryenTrapMode pass, run pass from s2wasm
jgravelle-google Aug 29, 2017
f092e0c
BinaryenTrapMode pass takes trap context as a parameter
jgravelle-google Aug 30, 2017
54c3558
Pass fully supports non-trapping binary ops
jgravelle-google Aug 30, 2017
39a24ab
Defer adding functions until after iteration (hackily)
jgravelle-google Aug 30, 2017
a8a93a9
Update asm2wasm to work with deferred function adding, rebuild tests
jgravelle-google Aug 30, 2017
1f75d79
Extract makeTrappingFloatToInt32
jgravelle-google Aug 30, 2017
ccf9652
Extract makeTrappingFloatToInt64
jgravelle-google Aug 30, 2017
926d6d8
Add unary conversions to trap pass
jgravelle-google Aug 30, 2017
8f75232
Add functions in the pass itself
jgravelle-google Aug 30, 2017
1806b49
Set s2wasm trap mode with command-line arguments
jgravelle-google Aug 31, 2017
deae722
Print BINARYEN_PASS_DEBUG state when testing
jgravelle-google Aug 31, 2017
cdc1bd6
Get asm2wasm using the BinaryenTrapMode pass instead of handling it i…
jgravelle-google Aug 31, 2017
1984a6e
Also handle f32 to int in asm2wasm
jgravelle-google Aug 31, 2017
060a026
Make BinaryenTrapMode only need a FloatTrapMode from the caller
jgravelle-google Aug 31, 2017
9d26a1c
Just pass the current binary Expression directly
jgravelle-google Aug 31, 2017
2e6bfa2
Combine makeTrappingI32Binary with makeTrappingI64Binary
jgravelle-google Aug 31, 2017
3c6bc15
Pass Unary expr to makeTrappingFloatToInt32
jgravelle-google Sep 1, 2017
a7d6b45
Unify makeTrappingFloatToInt32 & 64
jgravelle-google Sep 5, 2017
bd9fd92
Move makeTrapping* functions inside BinaryenTrapMode, make addedFunct…
jgravelle-google Sep 5, 2017
be19ee4
Remove FloatTrapContext
jgravelle-google Sep 5, 2017
0a3231e
Minor cleanups
jgravelle-google Sep 5, 2017
6eaf44c
Extract some smaller subfunctions
jgravelle-google Sep 5, 2017
a630144
Emit name switch/casing, rename is32Bit to isI64 for consistency
jgravelle-google Sep 5, 2017
95b0c24
Rename BinaryenTrapMode to FloatTrap, make trap mode a nested enum
jgravelle-google Sep 6, 2017
1f890bc
Add some comments explaining why FloatTrap is non-parallel
jgravelle-google Sep 6, 2017
a4a7f8b
Rename addedFunctions to generatedFunctions for precision
jgravelle-google Sep 6, 2017
c930ca9
Rename move and split float-clamp.h to passes/FloatTrap.(h|cpp)
jgravelle-google Sep 6, 2017
1ff90bb
Use builder instead of allocator
jgravelle-google Sep 6, 2017
bae7c43
Instantiate trap handling passes via the pass manager
jgravelle-google Sep 7, 2017
e692a90
Move passes/FloatTrap.h to ast/trapping.h
jgravelle-google Sep 7, 2017
1c2c22a
Add helper function to add trap-handling passes
jgravelle-google Sep 7, 2017
d1d7343
Add trap mode pass tests
jgravelle-google Sep 8, 2017
18b9b70
Rename FloatTrap.cpp to TrapMode.cpp
jgravelle-google Sep 8, 2017
317793a
Add s2wasm trap mode tests. Force float->int conversion to be signed
jgravelle-google Sep 8, 2017
33cbbc8
Add trapping_sint_div_s test to unit.asm.js
jgravelle-google Sep 8, 2017
85b8dc4
Fix flake8 issues with test scripts
jgravelle-google Sep 12, 2017
0d9301f
Update pass description comment
jgravelle-google Sep 12, 2017
3d8ce62
Extract building functions methods
jgravelle-google Sep 14, 2017
a63c311
Make generate functions into top-level functions
jgravelle-google Sep 14, 2017
3c9bab2
Add GeneratedTrappingFunctions class to manage function/import additions
jgravelle-google Sep 27, 2017
da95b72
Move ensure/makeTrapping functions outside class scope
jgravelle-google Sep 28, 2017
c6c45f0
Use GeneratedTrappingFunctions to add immediately in asm2wasm mode
jgravelle-google Sep 28, 2017
34e4f92
Remove trapping_sint_div_s test
jgravelle-google Sep 29, 2017
652ac6b
Review feedback, add validator/*.wasm to .gitignore
jgravelle-google Sep 29, 2017
c9fdeca
Add support for unsigned float-to-int conversion
jgravelle-google Sep 29, 2017
51ed481
Use opcode directly instead of bools
jgravelle-google Sep 29, 2017
3ecd486
Update s2wasm clamp test for unsigned ftoi
jgravelle-google Oct 2, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ trace.cpp
test/wasm-binaries-*.tbz2
test/wasm-torture-s-*.tbz2
test/wasm-install/
test/validator/*.wasm

*.pyc
CMakeFiles/
Expand Down
127 changes: 5 additions & 122 deletions check.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@

from scripts.test.support import run_command, split_wast
from scripts.test.shared import (
ASM2WASM, BIN_DIR, EMCC, MOZJS, NATIVECC, NATIVEXX, NODEJS, S2WASM_EXE,
BIN_DIR, EMCC, MOZJS, NATIVECC, NATIVEXX, NODEJS, S2WASM_EXE,
WASM_AS, WASM_CTOR_EVAL, WASM_OPT, WASM_SHELL, WASM_MERGE, WASM_SHELL_EXE,
WASM_DIS, WASM_REDUCE, binary_format_check, delete_from_orbit, fail, fail_with_error,
fail_if_not_identical, fail_if_not_contained, has_vanilla_emcc,
has_vanilla_llvm, minify_check, num_failures, options, tests,
requested, warnings, has_shell_timeout
)

import scripts.test.asm2wasm as asm2wasm
import scripts.test.s2wasm as s2wasm
import scripts.test.wasm2asm as wasm2asm

Expand Down Expand Up @@ -144,6 +145,7 @@ def run_wasm_opt_tests():
actual = actual.replace('printing before:\n', '')

expected = open(f, 'rb').read()

if actual != expected:
fail(actual, expected)

Expand All @@ -152,126 +154,6 @@ def run_wasm_opt_tests():

minify_check(t)

def run_asm2wasm_tests():
print '[ checking asm2wasm testcases... ]\n'

for asm in tests:
if asm.endswith('.asm.js'):
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 += ['--emit-potential-traps', '--ignore-implicit-traps']
wasm += '.imprecise'
elif precise == 2:
cmd += ['--emit-clamped-potential-traps']
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'
do_asm2wasm_test()
del os.environ['BINARYEN_PASS_DEBUG']
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, e:
fail_with_error('wasm interpreter error: ' + err) # failed to pretty-print
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')
payload = 'http://example.org/' + jsmap
assert len(payload) < 256, 'name too long'
url_section_contents = bytearray([len(payload)]) + bytearray(payload)
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')
if url_section_contents not in binary_contents[binary_contents.index(url_section_name):]:
fail_with_error('source map url not found in url section')


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'

def run_wasm_dis_tests():
print '\n[ checking wasm-dis on provided binaries... ]\n'

Expand Down Expand Up @@ -717,7 +599,8 @@ def execute():
# Run all the tests
run_help_tests()
run_wasm_opt_tests()
run_asm2wasm_tests()
asm2wasm.test_asm2wasm()
asm2wasm.test_asm2wasm_binary()
run_wasm_dis_tests()
run_wasm_merge_tests()
run_ctor_eval_tests()
Expand Down
160 changes: 160 additions & 0 deletions scripts/test/asm2wasm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#!/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():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any changes in this content, or just moved out from shared?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just moved from shared

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 += ['--emit-potential-traps', '--ignore-implicit-traps']
wasm += '.imprecise'
elif precise == 2:
cmd += ['--emit-clamped-potential-traps']
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()
Loading