Skip to content

Commit 0227fde

Browse files
committed
Merge branch 'incoming' of https://github.com/jpernst/emscripten into incoming
2 parents 9e90a54 + e0690b4 commit 0227fde

File tree

5 files changed

+88
-18
lines changed

5 files changed

+88
-18
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,3 +299,4 @@ a license to everyone to use it as detailed in LICENSE.)
299299
* Ryan Lester <ryan@cyph.com> (copyright owned by Cyph, Inc.)
300300
* Jameson Ernst <jameson@jpernst.com>
301301
* Yoan Lecoq <yoanlecoq.io@gmail.com>
302+
* Nazar Mokrynskyi <nazar@mokrynskyi.com>

site/source/docs/api_reference/module.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ The following ``Module`` attributes affect code execution.
8181

8282
If ``noExitRuntime`` is set to ``true``, the runtime is not shut down after ``run`` completes. Shutting down the runtime calls shutdown callbacks, for example ``atexit`` calls. If you want to continue using the code after ``run()`` finishes, it is necessary to set this. This is automatically set for you if you use an API command that implies that you want the runtime to not be shut down, for example ``emscripten_set_main_loop``.
8383

84+
.. js:attribute:: Module.onRuntimeInitialized
85+
86+
If set, this function is called when the runtime is fully initialized, that is, when compiled code is safe to run, which is after any asynchronous startup operations have completed (such as asynchronous WebAssembly compilation, file preloading, etc.). (An alternative to waiting for this to be called is to wait for ``main()`` to be called.)
87+
88+
.. js:attribute:: Module.onAbort
89+
90+
If set, this function is called when abnormal program termination occurs. That can happen due to the C method ``abort()`` being called directly, or called from JavaScript, or due to a fatal problem such as being unable to fetch a necessary file during startup (like the wasm binary when running wasm), etc. After calling this function, program termination occurs (i.e., you can't use this to try to do something else instead of stopping; there is no possibility of recovering here).
91+
8492
.. js:attribute:: Module.filePackagePrefixURL
8593

8694
This is the "prefix" URL for a preloaded data file that is hosted separately from its JavaScript and HTML files (it includes the full path up to, but not including, the data file). See :ref:`packaging-files-data-file-location` for more information.

src/preamble.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2496,6 +2496,12 @@ function integrateWasmJS(Module) {
24962496
// try the methods. each should return the exports if it succeeded
24972497

24982498
var exports;
2499+
#if BINARYEN_METHOD == 'native-wasm'
2500+
exports = doNativeWasm(global, env, providedBuffer);
2501+
#else
2502+
#if BINARYEN_METHOD == 'asmjs'
2503+
exports = doJustAsm(global, env, providedBuffer);
2504+
#else
24992505
var methods = method.split(',');
25002506

25012507
for (var i = 0; i < methods.length; i++) {
@@ -2519,6 +2525,8 @@ function integrateWasmJS(Module) {
25192525
}
25202526

25212527
if (!exports) throw 'no binaryen method succeeded. consider enabling more options, like interpreting, if you want that: https://github.com/kripken/emscripten/wiki/WebAssembly#binaryen-methods';
2528+
#endif
2529+
#endif
25222530

25232531
#if RUNTIME_LOGGING
25242532
Module['printErr']('binaryen method succeeded.');

tests/test_other.py

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3196,26 +3196,77 @@ def test_warn_unaligned(self):
31963196
assert '@line 11 "src.cpp"' in output[1], output[1]
31973197

31983198
def test_on_abort(self):
3199-
cmd = [PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), '-s', 'WASM=1', '-s', 'BINARYEN_METHOD="interpret-binary"']
3199+
expected_output = 'Module.onAbort was called'
32003200

3201-
self.clear()
3202-
proc = Popen(cmd, stdout=PIPE, stderr=PIPE)
3203-
output, err = proc.communicate()
3201+
def add_on_abort_and_verify():
3202+
with open('a.out.js') as f:
3203+
js = f.read()
3204+
with open('a.out.js', 'w') as f:
3205+
f.write("var Module = { onAbort: function() { console.log('%s') } };\n" % expected_output)
3206+
f.write(js)
3207+
self.assertContained(expected_output, run_js('a.out.js', assert_returncode=None))
32043208

3205-
expectedOutput = 'Module.onAbort was called'
3209+
# test direct abort() C call
32063210

3207-
# trigger onAbort by intentionally causing startup to fail
3208-
os.remove('a.out.wasm')
3211+
with open('src.c', 'w') as f:
3212+
f.write('''
3213+
#include <stdlib.h>
3214+
int main() {
3215+
abort();
3216+
}
3217+
''')
3218+
subprocess.check_call([PYTHON, EMCC, 'src.c'])
3219+
add_on_abort_and_verify()
32093220

3210-
f = open('a.out.js', 'r')
3211-
js = f.read()
3212-
f.close()
3213-
f = open('a.out.js', 'w')
3214-
f.write("var Module = {onAbort: function() { console.log('%s') }};\n" % expectedOutput)
3215-
f.write(js)
3216-
f.close()
3221+
# test direct abort() JS call
32173222

3218-
self.assertContained(expectedOutput, run_js('a.out.js', assert_returncode=None))
3223+
with open('src.c', 'w') as f:
3224+
f.write('''
3225+
#include <emscripten.h>
3226+
int main() {
3227+
EM_ASM({ abort() });
3228+
}
3229+
''')
3230+
subprocess.check_call([PYTHON, EMCC, 'src.c'])
3231+
add_on_abort_and_verify()
3232+
3233+
# test throwing in an abort handler, and catching that
3234+
3235+
with open('src.c', 'w') as f:
3236+
f.write('''
3237+
#include <emscripten.h>
3238+
int main() {
3239+
EM_ASM({
3240+
try {
3241+
Module.print('first');
3242+
abort();
3243+
} catch (e) {
3244+
Module.print('second');
3245+
abort();
3246+
throw e;
3247+
}
3248+
});
3249+
}
3250+
''')
3251+
subprocess.check_call([PYTHON, EMCC, 'src.c'])
3252+
with open('a.out.js') as f:
3253+
js = f.read()
3254+
with open('a.out.js', 'w') as f:
3255+
f.write("var Module = { onAbort: function() { console.log('%s'); throw 're-throw'; } };\n" % expected_output)
3256+
f.write(js)
3257+
out = run_js('a.out.js', stderr=subprocess.STDOUT, assert_returncode=None)
3258+
print out
3259+
self.assertContained(expected_output, out)
3260+
self.assertContained('re-throw', out)
3261+
self.assertContained('first', out)
3262+
self.assertContained('second', out)
3263+
self.assertEqual(out.count(expected_output), 2)
3264+
3265+
# test an abort during startup
3266+
3267+
subprocess.check_call([PYTHON, EMCC, path_from_root('tests', 'hello_world.c'), '-s', 'WASM=1', '-s', 'BINARYEN_METHOD="interpret-binary"'])
3268+
os.remove('a.out.wasm') # trigger onAbort by intentionally causing startup to fail
3269+
add_on_abort_and_verify()
32193270

32203271
def test_no_exit_runtime(self):
32213272
open('code.cpp', 'w').write(r'''

tools/ports/binaryen.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,11 @@ def create():
2929
return [shared.Cache.get('binaryen_tag_' + TAG, create, what='port', extension='.txt')]
3030

3131
def process_args(ports, args, settings, shared):
32-
if not needed(settings, shared, ports):
33-
return args
34-
get(ports, settings, shared)
32+
# we don't need to do anything just for compile args; binaryen
33+
# is used in the final link stage to wasm, not bitcode
34+
# (otherwise, if we get binaryen while building to bitcode, we
35+
# may be building system libraries, so this would be recursive.
36+
# TODO: consider avoiding such recursion in a more direct way)
3537
return args
3638

3739
def show():

0 commit comments

Comments
 (0)