Skip to content

Switch binaryen.js/wasm to ESM #4280

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 5 commits into from
Oct 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ full changeset diff at the end of each section.
Current Trunk
-------------

- JS and Wasm builds now emit ECMAScript modules. New usage is:
```js
import Binaryen from "path/to/binaryen.js";
const binaryen = await Binaryen();
...
```

v102
----

Expand Down
8 changes: 4 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -362,10 +362,10 @@ if(EMSCRIPTEN)
target_link_libraries(binaryen_wasm wasm asmjs emscripten-optimizer passes ir cfg support wasm)
target_link_libraries(binaryen_wasm "-s NO_FILESYSTEM=0")
target_link_libraries(binaryen_wasm "-s NODERAWFS=0")
target_link_libraries(binaryen_wasm "-s EXPORT_NAME=binaryen")
target_link_libraries(binaryen_wasm "-s EXPORT_NAME=Binaryen")
target_link_libraries(binaryen_wasm "-s EXPORT_ES6=1")
target_link_libraries(binaryen_wasm "--post-js ${CMAKE_CURRENT_SOURCE_DIR}/src/js/binaryen.js-post.js")
target_link_libraries(binaryen_wasm "--extern-pre-js ${CMAKE_CURRENT_SOURCE_DIR}/src/js/binaryen.js-extern-pre.js")
target_link_libraries(binaryen_wasm "--extern-post-js ${CMAKE_CURRENT_SOURCE_DIR}/src/js/binaryen.js-extern-post.js")
target_link_libraries(binaryen_wasm optimized "--closure 1")
target_link_libraries(binaryen_wasm optimized "--closure-args \"--language_in=ECMASCRIPT6 --language_out=ECMASCRIPT6\"")
target_link_libraries(binaryen_wasm optimized "-flto")
Expand All @@ -386,10 +386,10 @@ if(EMSCRIPTEN)
endif()
target_link_libraries(binaryen_js "-s NO_FILESYSTEM=0")
target_link_libraries(binaryen_js "-s NODERAWFS=0")
target_link_libraries(binaryen_js "-s EXPORT_NAME=binaryen")
target_link_libraries(binaryen_js "-s EXPORT_NAME=Binaryen")
target_link_libraries(binaryen_js "-s EXPORT_ES6=1")
target_link_libraries(binaryen_js "--post-js ${CMAKE_CURRENT_SOURCE_DIR}/src/js/binaryen.js-post.js")
target_link_libraries(binaryen_js "--extern-pre-js ${CMAKE_CURRENT_SOURCE_DIR}/src/js/binaryen.js-extern-pre.js")
target_link_libraries(binaryen_js "--extern-post-js ${CMAKE_CURRENT_SOURCE_DIR}/src/js/binaryen.js-extern-post.js")
target_link_libraries(binaryen_js optimized "--closure 1")
target_link_libraries(binaryen_js optimized "--closure-args \"--language_in=ECMASCRIPT6 --language_out=ECMASCRIPT6\"")
target_link_libraries(binaryen_js optimized "-flto")
Expand Down
25 changes: 17 additions & 8 deletions scripts/test/binaryenjs.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def do_test_binaryen_js_with(which):
if not s.endswith('.js'):
continue
print(s)
f = open('a.js', 'w')
f = open('a.mjs', 'w')
# avoid stdout/stderr ordering issues in some js shells - use just stdout
f.write('''
console.warn = console.error = console.log;
Expand All @@ -45,8 +45,7 @@ def do_test_binaryen_js_with(which):
f.write(support.js_test_wrap().replace('%TEST%', test_src))
f.close()

def test(engine):
cmd = [engine, 'a.js']
def test(cmd):
if 'fatal' not in s:
out = support.run_command(cmd, stderr=subprocess.STDOUT)
else:
Expand All @@ -58,10 +57,10 @@ def test(engine):

# run in all possible shells
if shared.MOZJS:
test(shared.MOZJS)
test([shared.MOZJS, '-m', 'a.mjs'])
if shared.NODEJS:
if node_has_wasm or 'WebAssembly.' not in test_src:
test(shared.NODEJS)
test([shared.NODEJS, 'a.mjs'])
else:
print('Skipping ' + test_path + ' because WebAssembly might not be supported')

Expand All @@ -80,20 +79,30 @@ def update_binaryen_js_tests():
for s in shared.get_tests(shared.get_test_dir('binaryen.js'), ['.js']):
basename = os.path.basename(s)
print(basename)
f = open('a.js', 'w')
f = open('a.mjs', 'w')
# avoid stdout/stderr ordering issues in some js shells - use just stdout
f.write('''
console.warn = console.error = console.log;
''')
f.write(open(shared.BINARYEN_JS).read())
test_src = open(s).read()
f.write(support.js_test_wrap().replace('%TEST%', test_src))
f.close()
if shared.MOZJS or node_has_wasm or 'WebAssembly.' not in test_src:
cmd = [shared.MOZJS or shared.NODEJS, 'a.js']

def update(cmd):
if 'fatal' not in basename:
out = support.run_command(cmd, stderr=subprocess.STDOUT)
else:
# expect an error - the specific error code will depend on the vm
out = support.run_command(cmd, stderr=subprocess.STDOUT, expected_status=None)
with open(s + '.txt', 'w') as o:
o.write(out)

# run in available shell
if shared.MOZJS:
update([shared.MOZJS, '-m', 'a.mjs'])
elif node_has_wasm or 'WebAssembly.' not in test_src:
update([shared.NODEJS, 'a.mjs'])
else:
print('Skipping ' + basename + ' because WebAssembly might not be supported')

Expand Down
5 changes: 3 additions & 2 deletions scripts/test/support.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,9 @@ def js_test_wrap():
# common wrapper code for JS tests, waiting for binaryen.js to become ready
# and providing common utility used by all tests:
return '''
binaryen.ready.then(function() {
(async function __in_test_code__() {
var binaryen = await Binaryen()
function assert(x) { if (!x) throw Error('Test assertion failed'); }
%TEST%
});
})();
'''
8 changes: 0 additions & 8 deletions src/js/binaryen.js-extern-post.js

This file was deleted.

6 changes: 4 additions & 2 deletions src/js/binaryen.js-extern-pre.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
var binaryen = {};
(function() {
// FIXME: The Emscripten shell requires this variable to be present, even though
// we are building to ES6 (where it doesn't exist) and the .wasm blob is inlined
// see: https://github.com/emscripten-core/emscripten/issues/11792
var __dirname = "";
38 changes: 2 additions & 36 deletions src/js/binaryen.js-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -4807,46 +4807,12 @@ Module['exit'] = function(status) {
if (status != 0) throw new Error('exiting due to error: ' + status);
};

// Indicates if Binaryen has been loaded and is ready
Module['isReady'] = runtimeInitialized;

// Provide a mechanism to tell when the module is ready
//
// if (!binaryen.isReady) await binaryen.ready;
// ...
//
let pendingPromises = [];
let initializeError = null;

Object.defineProperty(Module, 'ready', {
get() {
return new Promise((resolve, reject) => {
if (initializeError) {
reject(initializeError);
} else if (runtimeInitialized) {
resolve(Module);
} else {
pendingPromises.push({ resolve, reject });
}
});
}
});

// Intercept the onRuntimeInitialized hook if necessary
if (runtimeInitialized) {
initializeConstants();
} else {
Module['onRuntimeInitialized'] = (super_ => () => {
try {
initializeConstants();
if (super_) super_();
Module['isReady'] = true;
pendingPromises.forEach(p => { p.resolve(Module) });
} catch (e) {
initializeError = e;
pendingPromises.forEach(p => { p.reject(e) });
} finally {
pendingPromises = [];
}
initializeConstants();
if (super_) super_();
})(Module['onRuntimeInitialized']);
}
4 changes: 2 additions & 2 deletions test/binaryen.js/kitchen-sink.js
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ function test_relooper() {
var block0 = relooper.addBlock(makeCallCheck(0));
var block1 = relooper.addBlock(makeCallCheck(1));
var block2 = relooper.addBlock(makeCallCheck(2));
temp = makeDroppedInt32(10);
var temp = makeDroppedInt32(10);
relooper.addBranch(block0, block1, makeInt32(55), temp);
relooper.addBranch(block0, block2, null, makeDroppedInt32(20));
var body = relooper.renderAndDispose(block0, 0, module);
Expand Down Expand Up @@ -1006,7 +1006,7 @@ function test_interpret() {
module = new binaryen.Module();

module.addFunctionImport("print-i32", "spectest", "print", binaryen.i32, binaryen.none);
call = module.call("print-i32", [ makeInt32(1234) ], binaryen.None);
var call = module.call("print-i32", [ makeInt32(1234) ], binaryen.None);
var starter = module.addFunction("starter", binaryen.none, binaryen.none, [], call);
module.setStart(starter);

Expand Down