diff options
author | Jacob Gravelle <jgravelle@google.com> | 2018-01-22 12:50:36 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-22 12:50:36 -0800 |
commit | 02729a12e1735f629d3066b51c96a056f712b080 (patch) | |
tree | 353a495836776695d0f86f08b6292635c4dba101 /scripts | |
parent | b01f2bb237e086fe4ae852c6004297fa8f8b39c2 (diff) | |
download | binaryen-02729a12e1735f629d3066b51c96a056f712b080.tar.gz binaryen-02729a12e1735f629d3066b51c96a056f712b080.tar.bz2 binaryen-02729a12e1735f629d3066b51c96a056f712b080.zip |
First pass at LLD support for Emscripten (#1346)
* Skeleton of a beginning of o2wasm, WIP and probably not going to be used
* Get building post-cherry-pick
* ast->ir, remove commented out code, include a debug module print because linking
* Read linking section, print emscripten metadata json
* WasmBinaryWriter emits user sections on Module
* Remove debugging prints, everything that isn't needed to build metadata
* Rename o2wasm to lld-metadata
* lld-metadata support for outputting to file
* Use tables index instead of function index for initializer functions
* Add lld-emscripten tool to add emscripten-runtime functions to wasm modules (built with lld)
* Handle EM_ASM in lld-emscripten
* Add a list of functions to forcibly export (for initializer functions)
* Disable incorrect initializer function reading
* Add error printing when parsing .o files in lld-metadata
* Remove ';; METADATA: ' prefix from lld-metadata, output is now standalone json
* Support em_asm consts that aren't at the start of a segment
* Initial test framework for lld-metadata tool
* Add em_asm test
* Add support for WASM_INIT_FUNCS in the linking section
* Remove reloc section parsing because it's unused
* lld-emscripten can read and write text
* Add test harness for lld-emscripten
* Export all functions for now
* Add missing lld test output
* Add support for reading object files differently
Only difference so far is in importing mutable globals being an object
file representation for symbols, but invalid wasm.
* Update help strings
* Update linking tests for stackAlloc fix
* Rename lld-emscripten,lld-metadata to wasm-emscripten-finalize,wasm-link-metadata
* Add help text to header comments
* auto& instead of auto &
* Extract LinkType to abi/wasm-object.h
* Remove special handling for wasm object file reading, allow mutable globals
* Add braces around default switch case
* Fix flake8 errors
* Handle generating dyncall thunks for imports as well
* Use explicit bool for stackPointerGlobal
* Use glob patterns for lld file iteration
* Use __wasm_call_ctors for all initializer functions
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/test/generate_lld_tests.py | 84 | ||||
-rwxr-xr-x | scripts/test/lld.py | 62 | ||||
-rw-r--r-- | scripts/test/shared.py | 8 |
3 files changed, 154 insertions, 0 deletions
diff --git a/scripts/test/generate_lld_tests.py b/scripts/test/generate_lld_tests.py new file mode 100755 index 000000000..c959bd857 --- /dev/null +++ b/scripts/test/generate_lld_tests.py @@ -0,0 +1,84 @@ +#!/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 sys +from support import run_command +import shared + + +def files_with_extensions(path, extensions): + for file in sorted(os.listdir(path)): + _, ext = os.path.splitext(file) + if ext in extensions: + yield file, ext + + +def generate_object_files(clang_bin): + print '\n[ building object 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') + + src_path = os.path.join(lld_path, src_file) + obj_path = os.path.join(lld_path, obj_file) + run_command([ + clang_bin, src_path, '-o', obj_path, + '--target=wasm32-unknown-unknown-wasm', + '-c', + '-nostdinc', + '-Xclang', '-nobuiltininc', + '-Xclang', '-nostdsysteminc', + '-Xclang', '-I/s/work/emscripten/system/include', + '-O1', + ]) + + +def generate_wast_files(lld_bin): + print '\n[ linking wasm files from object files... ]\n' + + lld_path = os.path.join(shared.options.binaryen_test, 'lld') + for obj_file, ext in files_with_extensions(lld_path, ['.o']): + print '..', obj_file + wasm_file = obj_file.replace(ext, '.wasm') + wast_file = obj_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) + run_command([ + lld_bin, '-flavor', 'wasm', + '-z', '-stack-size=1048576', + obj_path, '-o', wasm_path, + '--entry=main', + '--allow-undefined', + '--export', '__wasm_call_ctors', + ]) + try: + run_command(shared.WASM_DIS + [wasm_path, '-o', wast_path]) + finally: + # Don't need the .wasm file, don't leave it around + shared.delete_from_orbit(wasm_path) + + +if __name__ == '__main__': + if len(sys.argv) != 3: + print 'Usage: generate_lld_tests.py [path/to/clang] [path/to/lld]' + sys.exit(1) + generate_object_files(sys.argv[1]) + generate_wast_files(sys.argv[2]) diff --git a/scripts/test/lld.py b/scripts/test/lld.py new file mode 100755 index 000000000..793031ca6 --- /dev/null +++ b/scripts/test/lld.py @@ -0,0 +1,62 @@ +#!/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 +from support import run_command +from shared import ( + fail, fail_with_error, files_with_pattern, options, + WASM_LINK_METADATA, WASM_EMSCRIPTEN_FINALIZE +) + + +def test_wasm_link_metadata(): + print '\n[ checking wasm-link-metadata testcases... ]\n' + + for obj_path in files_with_pattern(options.binaryen_test, 'lld', '*.o'): + print '..', obj_path + expected_file = obj_path.replace('.o', '.json') + + cmd = WASM_LINK_METADATA + [obj_path] + actual = run_command(cmd) + + if not os.path.exists(expected_file): + print actual + fail_with_error('output ' + expected_file + ' does not exist') + expected = open(expected_file, 'rb').read() + if actual != expected: + fail(actual, expected) + + +def test_wasm_emscripten_finalize(): + print '\n[ checking wasm-emscripten-finalize testcases... ]\n' + + for wast_path in files_with_pattern(options.binaryen_test, 'lld', '*.wast'): + print '..', wast_path + expected_file = wast_path + '.out' + cmd = WASM_EMSCRIPTEN_FINALIZE + [wast_path, '-S'] + actual = run_command(cmd) + + if not os.path.exists(expected_file): + print actual + fail_with_error('output ' + expected_file + ' does not exist') + expected = open(expected_file, 'rb').read() + if actual != expected: + fail(actual, expected) + + +if __name__ == '__main__': + test_wasm_link_metadata() + test_wasm_emscripten_finalize() diff --git a/scripts/test/shared.py b/scripts/test/shared.py index 9933f85e1..863e97ec0 100644 --- a/scripts/test/shared.py +++ b/scripts/test/shared.py @@ -1,5 +1,6 @@ import argparse import difflib +import glob import os import shutil import subprocess @@ -169,6 +170,9 @@ WASM_MERGE = [os.path.join(options.binaryen_bin, 'wasm-merge')] S2WASM = [os.path.join(options.binaryen_bin, 's2wasm')] WASM_REDUCE = [os.path.join(options.binaryen_bin, 'wasm-reduce')] WASM_METADCE = [os.path.join(options.binaryen_bin, 'wasm-metadce')] +WASM_LINK_METADATA = [os.path.join(options.binaryen_bin, 'wasm-link-metadata')] +WASM_EMSCRIPTEN_FINALIZE = [os.path.join(options.binaryen_bin, + 'wasm-emscripten-finalize')] S2WASM_EXE = S2WASM[0] WASM_SHELL_EXE = WASM_SHELL[0] @@ -429,3 +433,7 @@ def minify_check(wast, verify_final_result=True): 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))) |