add onRuntimeInitialized method; #3106

This commit is contained in:
Alon Zakai 2015-01-02 13:28:38 -08:00
Родитель 3af15fd320
Коммит 5b89c3388c
5 изменённых файлов: 59 добавлений и 13 удалений

Просмотреть файл

@ -207,6 +207,11 @@ or
What happens in practice is that when code is ready to be run, we check for ``Module._main``. If present, we call it. If a ``main()`` function was compiled from C, it will be there (and it will be a JavaScript function). But, you can also just define a JavaScript function there, either will work.
Another option is to define an ``onRuntimeInitialized`` function,
Module['onRuntimeInitialized'] = function() { ... };
That method will be called when the runtime is ready and it is ok for you to call compiled code. In practice, that is exactly the same time at which ``main()`` would be called, so ``onRuntimeInitialized`` doesn't let you do anything new, but it can be convenient in some cases - for example, if you use ``onRuntimeInitialized`` and don't define a ``main()`` function, then the runtime will not be shut down after ``main()`` exits, and you can keep calling compiled methods (you can also have a ``main()`` and build with ``-s NO_EXIT_RUNTIME=1`` to keep the runtime from being shut down). Thus, for libraries, ``onRuntimeInitialized`` can be convenient.
.. _faq-dead-code-elimination:

Просмотреть файл

@ -142,9 +142,9 @@ function run(args) {
Module.printErr('pre-main prep time: ' + (Date.now() - preloadStartTime) + ' ms');
}
if (Module['_main'] && shouldRunNow) {
Module['callMain'](args);
}
if (Module['onRuntimeInitialized']) Module['onRuntimeInitialized']();
if (Module['_main'] && shouldRunNow) Module['callMain'](args);
postRun();
}

Просмотреть файл

@ -9,7 +9,7 @@ char* EMSCRIPTEN_KEEPALIVE note(int n) {
EM_ASM_({ Module.print([$0, $1]) }, n, noted);
noted += n;
EM_ASM_({ Module.print(['noted is now', $0]) }, noted);
return "silly-string";
return (char*)"silly-string";
}
void free(void*) { // free is valid to call even after the runtime closes, so useful as a hack here for this test

Просмотреть файл

@ -0,0 +1,22 @@
#include <stdio.h>
#include <emscripten.h>
extern "C" {
int noted = 0;
char* EMSCRIPTEN_KEEPALIVE note(int n) {
EM_ASM_({ Module.print([$0, $1]) }, n, noted);
noted += n;
EM_ASM_({ Module.print(['noted is now', $0]) }, noted);
return (char*)"silly-string";
}
void free(void*) { // free is valid to call even after the runtime closes, so useful as a hack here for this test
EM_ASM_({ Module.print(['reporting', $0]) }, noted);
int result = noted;
REPORT_RESULT();
}
}

Просмотреть файл

@ -1850,15 +1850,34 @@ void *getBindBuffer() {
setTimeout(Module['_free'], 1000); // free is valid to call even after the runtime closes
'''
print 'mem init, so async, call too early'
open(os.path.join(self.get_dir(), 'post.js'), 'w').write(post_prep + post_test + post_hook)
self.btest('runtime_misuse.cpp', expected='600', args=['--post-js', 'post.js', '--memory-init-file', '1'])
print 'sync startup, call too late'
open(os.path.join(self.get_dir(), 'post.js'), 'w').write(post_prep + 'Module.postRun.push(function() { ' + post_test + ' });' + post_hook);
self.btest('runtime_misuse.cpp', expected='600', args=['--post-js', 'post.js', '--memory-init-file', '0'])
print 'sync, runtime still alive, so all good'
open(os.path.join(self.get_dir(), 'post.js'), 'w').write(post_prep + 'expected_ok = true; Module.postRun.push(function() { ' + post_test + ' });' + post_hook);
self.btest('runtime_misuse.cpp', expected='606', args=['--post-js', 'post.js', '--memory-init-file', '0', '-s', 'NO_EXIT_RUNTIME=1'])
open('pre_main.js', 'w').write(r'''
Module._main = function(){
myJSCallback();
return 0;
};
''')
open('pre_runtime.js', 'w').write(r'''
Module.onRuntimeInitialized = function(){
myJSCallback();
};
''')
for filename, extra_args, second_code in [
('runtime_misuse.cpp', [], 600),
('runtime_misuse_2.cpp', ['--pre-js', 'pre_main.js'], 600),
('runtime_misuse_2.cpp', ['--pre-js', 'pre_runtime.js'], 601) # 601, because no main means we *do* run another call after exit()
]:
print '\n', filename, extra_args
print 'mem init, so async, call too early'
open(os.path.join(self.get_dir(), 'post.js'), 'w').write(post_prep + post_test + post_hook)
self.btest(filename, expected='600', args=['--post-js', 'post.js', '--memory-init-file', '1'] + extra_args)
print 'sync startup, call too late'
open(os.path.join(self.get_dir(), 'post.js'), 'w').write(post_prep + 'Module.postRun.push(function() { ' + post_test + ' });' + post_hook);
self.btest(filename, expected=str(second_code), args=['--post-js', 'post.js', '--memory-init-file', '0'] + extra_args)
print 'sync, runtime still alive, so all good'
open(os.path.join(self.get_dir(), 'post.js'), 'w').write(post_prep + 'expected_ok = true; Module.postRun.push(function() { ' + post_test + ' });' + post_hook);
self.btest(filename, expected='606', args=['--post-js', 'post.js', '--memory-init-file', '0', '-s', 'NO_EXIT_RUNTIME=1'] + extra_args)
def test_worker_api(self):
Popen([PYTHON, EMCC, path_from_root('tests', 'worker_api_worker.cpp'), '-o', 'worker.js', '-s', 'BUILD_AS_WORKER=1', '-s', 'EXPORTED_FUNCTIONS=["_one"]']).communicate()