summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorJacob Gravelle <jgravelle@google.com>2018-01-22 12:50:36 -0800
committerGitHub <noreply@github.com>2018-01-22 12:50:36 -0800
commit02729a12e1735f629d3066b51c96a056f712b080 (patch)
tree353a495836776695d0f86f08b6292635c4dba101 /scripts
parentb01f2bb237e086fe4ae852c6004297fa8f8b39c2 (diff)
downloadbinaryen-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-xscripts/test/generate_lld_tests.py84
-rwxr-xr-xscripts/test/lld.py62
-rw-r--r--scripts/test/shared.py8
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)))