Skip to content

Don't inclue mem init loading code when it is inside the wasm anyhow #5844

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 8 commits into from
Dec 8, 2017
10 changes: 7 additions & 3 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1176,6 +1176,11 @@ def check(input_file):
if shared.Settings.BINARYEN_PASSES:
shared.Settings.BINARYEN_PASSES += ','
shared.Settings.BINARYEN_PASSES += 'safe-heap'
# we will include the mem init data in the wasm, when we don't need the
# mem init file to be loadable by itself
shared.Settings.MEM_INIT_IN_WASM = 'asmjs' not in shared.Settings.BINARYEN_METHOD and \
'interpret-asm2wasm' not in shared.Settings.BINARYEN_METHOD and \
not shared.Settings.USE_PTHREADS

# wasm outputs are only possible with a side wasm
if target.endswith(WASM_ENDINGS):
Expand Down Expand Up @@ -1709,7 +1714,7 @@ def repl(m):
if not shared.Settings.BINARYEN or 'asmjs' in shared.Settings.BINARYEN_METHOD or 'interpret-asm2wasm' in shared.Settings.BINARYEN_METHOD:
return 'memoryInitializer = "%s";' % shared.JS.get_subresource_location(memfile, embed_memfile(options))
else:
return 'memoryInitializer = null;'
return ''
src = re.sub(shared.JS.memory_initializer_pattern, repl, open(final).read(), count=1)
open(final + '.mem.js', 'w').write(src)
final += '.mem.js'
Expand Down Expand Up @@ -2299,8 +2304,7 @@ def do_binaryen(target, asm_target, options, memfile, wasm_binary_target,
cmd.append(shared.Building.opt_level_to_str(options.opt_level, options.shrink_level))
# import mem init file if it exists, and if we will not be using asm.js as a binaryen method (as it needs the mem init file, of course)
mem_file_exists = options.memory_init_file and os.path.exists(memfile)
ok_binaryen_method = 'asmjs' not in shared.Settings.BINARYEN_METHOD and 'interpret-asm2wasm' not in shared.Settings.BINARYEN_METHOD
import_mem_init = mem_file_exists and ok_binaryen_method
import_mem_init = mem_file_exists and shared.Settings.MEM_INIT_IN_WASM
if import_mem_init:
cmd += ['--mem-init=' + memfile]
if not shared.Settings.RELOCATABLE:
Expand Down
2 changes: 2 additions & 0 deletions src/postamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Module['asm'] = asm;
{{{ maybeExport('FS') }}}
{{{ maybeExport('GL') }}}

#if MEM_INIT_IN_WASM == 0
#if MEM_INIT_METHOD == 2
#if USE_PTHREADS
if (memoryInitializer && !ENVIRONMENT_IS_PTHREAD) (function(s) {
Expand Down Expand Up @@ -110,6 +111,7 @@ if (memoryInitializer) {
}
}
#endif
#endif // MEM_INIT_IN_WASM == 0

#if CYBERDWARF
Module['cyberdwarf'] = _cyberdwarf_Debugger(cyberDWARFFile);
Expand Down
2 changes: 2 additions & 0 deletions src/preamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -2106,10 +2106,12 @@ function integrateWasmJS() {
var oldView = new Int8Array(oldBuffer);
var newView = new Int8Array(newBuffer);

#if MEM_INIT_IN_WASM == 0
// If we have a mem init file, do not trample it
if (!memoryInitializer) {
oldView.set(newView.subarray(Module['STATIC_BASE'], Module['STATIC_BASE'] + Module['STATIC_BUMP']), Module['STATIC_BASE']);
}
#endif

newView.set(oldView);
updateGlobalBuffer(newBuffer);
Expand Down
2 changes: 2 additions & 0 deletions src/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -861,5 +861,7 @@ var WASM_BINARY_FILE = ''; // name of the file containing wasm binary, if releva
var ASMJS_CODE_FILE = ''; // name of the file containing asm.js, if relevant
var SOURCE_MAP_BASE = ''; // Base URL the source mapfile, if relevant

var MEM_INIT_IN_WASM = 0; // for internal use only

var SUPPORT_BASE64_EMBEDDING = 0; // If set to 1, src/base64Utils.js will be included in the bundle.
// This is set internally when needed (SINGLE_FILE)
36 changes: 36 additions & 0 deletions tests/pthread/test_pthread_global_data_initialization.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#include <assert.h>
#include <pthread.h>
#include <emscripten.h>

int globalData = 1;

void *thread_main(void *arg)
{
EM_ASM(Module.print('hello from pthread 1: ' + $0), globalData);
assert(globalData == 10);

globalData = 20;
EM_ASM(Module.print('hello from pthread 2: ' + $0), globalData);
assert(globalData == 20);
return 0;
}

int main()
{
EM_ASM(Module.print('hello from main 1: ' + $0), globalData);
assert(globalData == 1);

globalData = 10;
EM_ASM(Module.print('hello from main 2: ' + $0), globalData);
assert(globalData == 10);

pthread_t thread;
pthread_create(&thread, NULL, thread_main, NULL);
pthread_join(thread, 0);

EM_ASM(Module.print('hello from main 3: ' + $0), globalData);
assert(globalData == 20);
#ifdef REPORT_RESULT
REPORT_RESULT(globalData);
#endif
}
6 changes: 6 additions & 0 deletions tests/test_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -3329,6 +3329,12 @@ def test_pthread_call_async_on_main_thread(self):
self.btest(path_from_root('tests', 'pthread', 'call_async_on_main_thread.c'), expected='7', args=['-O3', '-s', 'USE_PTHREADS=1', '-DPROXY_TO_PTHREAD=0', '--js-library', path_from_root('tests', 'pthread', 'call_async_on_main_thread.js')])
self.btest(path_from_root('tests', 'pthread', 'call_async_on_main_thread.c'), expected='7', args=['-Oz', '-DPROXY_TO_PTHREAD=0', '--js-library', path_from_root('tests', 'pthread', 'call_async_on_main_thread.js')])

# Tests that spawning a new thread does not cause a reinitialization of the global data section of the application memory area.
def test_pthread_global_data_initialization(self):
for mem_init_mode in [[], ['--memory-init-file', '0'], ['--memory-init-file', '1']]:
for args in [[], ['-O3']]:
self.btest(path_from_root('tests', 'pthread', 'test_pthread_global_data_initialization.c'), expected='20', args=args+mem_init_mode+['-s', 'USE_PTHREADS=1', '-s', 'PROXY_TO_PTHREAD=1'], also_wasm=False)

# test atomicrmw i64
def test_atomicrmw_i64(self):
Popen([PYTHON, EMCC, path_from_root('tests', 'atomicrmw_i64.ll'), '-s', 'USE_PTHREADS=1', '-s', 'IN_TEST_HARNESS=1', '-o', 'test.html']).communicate()
Expand Down