Skip to content

Commit dee8676

Browse files
authored
Initial support for pthreads with wasm (#5710)
Also adds support for testing with wasm in addition to JS+SAB. To enable testing, set `EMCC_BROWSER_ALSO_WASM=1` and run `browser.test_pthread*`. Works with EMSCRIPTEN_BROWSER='/path/to/chrome --user-data-dir=clean_dir --js-flags=--experimental-wasm-threads --enable-features=WebAssembly --disable-features=WebAssemblyTrapHandler' with recent (canary) chrome, and also with firefox nightly.
1 parent 4fd5b60 commit dee8676

File tree

6 files changed

+123
-61
lines changed

6 files changed

+123
-61
lines changed

emcc.py

+38-43
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@
101101
final = None
102102

103103

104+
def exit_with_error(message):
105+
logging.error(message)
106+
exit(1)
107+
104108
class Intermediate(object):
105109
counter = 0
106110
def save_intermediate(name=None, suffix='js'):
@@ -737,8 +741,7 @@ def setting_sub(s):
737741

738742
if not arg.startswith('-'):
739743
if not os.path.exists(arg):
740-
logging.error('%s: No such file or directory ("%s" was expected to be an input file, based on the commandline arguments provided)', arg, arg)
741-
exit(1)
744+
exit_with_error('%s: No such file or directory ("%s" was expected to be an input file, based on the commandline arguments provided)', arg, arg)
742745

743746
arg_ending = filename_type_ending(arg)
744747
if arg_ending.endswith(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + ASSEMBLY_ENDINGS + HEADER_ENDINGS) or shared.Building.is_ar(arg): # we already removed -o <target>, so all these should be inputs
@@ -766,18 +769,17 @@ def setting_sub(s):
766769
elif arg_ending.endswith(STATICLIB_ENDINGS):
767770
if not shared.Building.is_ar(arg):
768771
if shared.Building.is_bitcode(arg):
769-
logging.error(arg + ': File has a suffix of a static library ' + str(STATICLIB_ENDINGS) + ', but instead is an LLVM bitcode file! When linking LLVM bitcode files, use one of the suffixes ' + str(BITCODE_ENDINGS))
772+
message = arg + ': File has a suffix of a static library ' + str(STATICLIB_ENDINGS) + ', but instead is an LLVM bitcode file! When linking LLVM bitcode files, use one of the suffixes ' + str(BITCODE_ENDINGS)
770773
else:
771-
logging.error(arg + ': Unknown format, not a static library!')
772-
exit(1)
774+
message = arg + ': Unknown format, not a static library!'
775+
exit_with_error(message)
773776
else:
774777
if has_fixed_language_mode:
775778
newargs[i] = ''
776779
input_files.append((i, arg))
777780
has_source_inputs = True
778781
else:
779-
logging.error(arg + ": Input file has an unknown suffix, don't know what to do with it!")
780-
exit(1)
782+
exit_with_error(arg + ": Input file has an unknown suffix, don't know what to do with it!")
781783
elif arg.startswith('-L'):
782784
lib_dirs.append(arg[2:])
783785
newargs[i] = ''
@@ -862,8 +864,7 @@ def check(input_file):
862864
input_files = [(i, input_file) for (i, input_file) in input_files if check(input_file)]
863865

864866
if len(input_files) == 0:
865-
logging.error('no input files\nnote that input files without a known suffix are ignored, make sure your input files end with one of: ' + str(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + STATICLIB_ENDINGS + ASSEMBLY_ENDINGS + HEADER_ENDINGS))
866-
exit(1)
867+
exit_with_error('no input files\nnote that input files without a known suffix are ignored, make sure your input files end with one of: ' + str(SOURCE_ENDINGS + BITCODE_ENDINGS + DYNAMICLIB_ENDINGS + STATICLIB_ENDINGS + ASSEMBLY_ENDINGS + HEADER_ENDINGS))
867868

868869
newargs = CC_ADDITIONAL_ARGS + newargs
869870

@@ -933,8 +934,7 @@ def check(input_file):
933934
assert shared.Settings.PGO == 0, 'pgo not supported in fastcomp'
934935
assert shared.Settings.QUANTUM_SIZE == 4, 'altering the QUANTUM_SIZE is not supported'
935936
except Exception as e:
936-
logging.error('Compiler settings are incompatible with fastcomp. You can fall back to the older compiler core, although that is not recommended, see http://kripken.github.io/emscripten-site/docs/building_from_source/LLVM-Backend.html')
937-
raise e
937+
exit_with_error('Compiler settings are incompatible with fastcomp. You can fall back to the older compiler core, although that is not recommended, see http://kripken.github.io/emscripten-site/docs/building_from_source/LLVM-Backend.html')
938938

939939
assert not shared.Settings.PGO, 'cannot run PGO in ASM_JS mode'
940940

@@ -949,8 +949,7 @@ def check(input_file):
949949
if options.use_closure_compiler:
950950
shared.Settings.USE_CLOSURE_COMPILER = options.use_closure_compiler
951951
if not shared.check_closure_compiler():
952-
logging.error('fatal: closure compiler is not configured correctly')
953-
sys.exit(1)
952+
exit_with_error('fatal: closure compiler is not configured correctly')
954953
if options.use_closure_compiler == 2 and shared.Settings.ASM_JS == 1:
955954
shared.WarningManager.warn('ALMOST_ASM', 'not all asm.js optimizations are possible with --closure 2, disabling those - your code will be run more slowly')
956955
shared.Settings.ASM_JS = 2
@@ -1007,8 +1006,7 @@ def check(input_file):
10071006
shared.Settings.NO_FILESYSTEM = 1
10081007
shared.Settings.FETCH = 1
10091008
if not shared.Settings.USE_PTHREADS:
1010-
logging.error('-s ASMFS=1 requires either -s USE_PTHREADS=1 or -s USE_PTHREADS=2 to be set!')
1011-
sys.exit(1)
1009+
exit_with_error('-s ASMFS=1 requires either -s USE_PTHREADS=1 or -s USE_PTHREADS=2 to be set!')
10121010

10131011
if shared.Settings.FETCH and final_suffix in JS_CONTAINING_SUFFIXES:
10141012
input_files.append((next_arg_index, shared.path_from_root('system', 'lib', 'fetch', 'emscripten_fetch.cpp')))
@@ -1083,24 +1081,18 @@ def check(input_file):
10831081

10841082
if shared.Settings.USE_PTHREADS:
10851083
if shared.Settings.LINKABLE:
1086-
logging.error('-s LINKABLE=1 is not supported with -s USE_PTHREADS>0!')
1087-
exit(1)
1084+
exit_with_error('-s LINKABLE=1 is not supported with -s USE_PTHREADS>0!')
10881085
if shared.Settings.SIDE_MODULE:
1089-
logging.error('-s SIDE_MODULE=1 is not supported with -s USE_PTHREADS>0!')
1090-
exit(1)
1086+
exit_with_error('-s SIDE_MODULE=1 is not supported with -s USE_PTHREADS>0!')
10911087
if shared.Settings.MAIN_MODULE:
1092-
logging.error('-s MAIN_MODULE=1 is not supported with -s USE_PTHREADS>0!')
1093-
exit(1)
1088+
exit_with_error('-s MAIN_MODULE=1 is not supported with -s USE_PTHREADS>0!')
10941089
if shared.Settings.EMTERPRETIFY:
1095-
logging.error('-s EMTERPRETIFY=1 is not supported with -s USE_PTHREADS>0!')
1096-
exit(1)
1090+
exit_with_error('-s EMTERPRETIFY=1 is not supported with -s USE_PTHREADS>0!')
10971091
if shared.Settings.PROXY_TO_WORKER:
1098-
logging.error('--proxy-to-worker is not supported with -s USE_PTHREADS>0! Use the option -s PROXY_TO_PTHREAD=1 if you want to run the main thread of a multithreaded application in a web worker.')
1099-
exit(1)
1092+
exit_with_error('--proxy-to-worker is not supported with -s USE_PTHREADS>0! Use the option -s PROXY_TO_PTHREAD=1 if you want to run the main thread of a multithreaded application in a web worker.')
11001093
else:
11011094
if shared.Settings.PROXY_TO_PTHREAD:
1102-
logging.error('-s PROXY_TO_PTHREAD=1 requires -s USE_PTHREADS to work!')
1103-
exit(1)
1095+
exit_with_error('-s PROXY_TO_PTHREAD=1 requires -s USE_PTHREADS to work!')
11041096

11051097
if shared.Settings.OUTLINING_LIMIT:
11061098
if not options.js_opts:
@@ -1120,13 +1112,20 @@ def check(input_file):
11201112
if not DEBUG:
11211113
misc_temp_files.note(asm_target)
11221114

1123-
assert shared.Settings.TOTAL_MEMORY >= 16*1024*1024, 'TOTAL_MEMORY must be at least 16MB, was ' + str(shared.Settings.TOTAL_MEMORY)
1115+
if shared.Settings.TOTAL_MEMORY < 16*1024*1024:
1116+
exit_with_error('TOTAL_MEMORY must be at least 16MB, was ' + str(shared.Settings.TOTAL_MEMORY))
11241117
if shared.Settings.BINARYEN:
1125-
assert shared.Settings.TOTAL_MEMORY % 65536 == 0, 'For wasm, TOTAL_MEMORY must be a multiple of 64KB, was ' + str(shared.Settings.TOTAL_MEMORY)
1118+
if shared.Settings.TOTAL_MEMORY % 65536 != 0:
1119+
exit_with_error('For wasm, TOTAL_MEMORY must be a multiple of 64KB, was ' + str(shared.Settings.TOTAL_MEMORY))
11261120
else:
1127-
assert shared.Settings.TOTAL_MEMORY % (16*1024*1024) == 0, 'For asm.js, TOTAL_MEMORY must be a multiple of 16MB, was ' + str(shared.Settings.TOTAL_MEMORY)
1128-
assert shared.Settings.TOTAL_MEMORY >= shared.Settings.TOTAL_STACK, 'TOTAL_MEMORY must be larger than TOTAL_STACK, was ' + str(shared.Settings.TOTAL_MEMORY) + ' (TOTAL_STACK=' + str(shared.Settings.TOTAL_STACK) + ')'
1129-
assert shared.Settings.WASM_MEM_MAX == -1 or shared.Settings.WASM_MEM_MAX % 65536 == 0, 'WASM_MEM_MAX must be a multiple of 64KB, was ' + str(shared.Settings.WASM_MEM_MAX)
1121+
if shared.Settings.TOTAL_MEMORY % (16*1024*1024) != 0:
1122+
exit_with_error('For asm.js, TOTAL_MEMORY must be a multiple of 16MB, was ' + str(shared.Settings.TOTAL_MEMORY))
1123+
if shared.Settings.TOTAL_MEMORY < shared.Settings.TOTAL_STACK:
1124+
exit_with_error('TOTAL_MEMORY must be larger than TOTAL_STACK, was ' + str(shared.Settings.TOTAL_MEMORY) + ' (TOTAL_STACK=' + str(shared.Settings.TOTAL_STACK) + ')')
1125+
if shared.Settings.WASM_MEM_MAX != -1 and shared.Settings.WASM_MEM_MAX % 65536 != 0:
1126+
exit_with_error('WASM_MEM_MAX must be a multiple of 64KB, was ' + str(shared.Settings.WASM_MEM_MAX))
1127+
if shared.Settings.USE_PTHREADS and shared.Settings.WASM and shared.Settings.ALLOW_MEMORY_GROWTH and shared.Settings.WASM_MEM_MAX == -1:
1128+
exit_with_error('If pthreads and memory growth are enabled, WASM_MEM_MAX must be set')
11301129

11311130
if shared.Settings.WASM_BACKEND:
11321131
options.js_opts = None
@@ -1150,7 +1149,6 @@ def check(input_file):
11501149
shared.Settings.ASM_JS = 2 # when targeting wasm, we use a wasm Memory, but that is not compatible with asm.js opts
11511150
shared.Settings.GLOBAL_BASE = 1024 # leave some room for mapping global vars
11521151
assert not shared.Settings.SPLIT_MEMORY, 'WebAssembly does not support split memory'
1153-
assert not shared.Settings.USE_PTHREADS, 'WebAssembly does not support pthreads'
11541152
if shared.Settings.ELIMINATE_DUPLICATE_FUNCTIONS:
11551153
logging.warning('for wasm there is no need to set ELIMINATE_DUPLICATE_FUNCTIONS, the binaryen optimizer does it automatically')
11561154
shared.Settings.ELIMINATE_DUPLICATE_FUNCTIONS = 0
@@ -1337,8 +1335,7 @@ def compile_source_file(i, input_file):
13371335
logging.debug("running: " + ' '.join(shared.Building.doublequote_spaces(args))) # NOTE: Printing this line here in this specific format is important, it is parsed to implement the "emcc --cflags" command
13381336
execute(args) # let compiler frontend print directly, so colors are saved (PIPE kills that)
13391337
if not os.path.exists(output_file):
1340-
logging.error('compiler frontend failed to generate LLVM bitcode, halting')
1341-
sys.exit(1)
1338+
exit_with_error('compiler frontend failed to generate LLVM bitcode, halting')
13421339

13431340
# First, generate LLVM bitcode. For each input file, we get base.o with bitcode
13441341
for i, input_file in input_files:
@@ -1362,8 +1359,7 @@ def compile_source_file(i, input_file):
13621359
if has_fixed_language_mode:
13631360
compile_source_file(i, input_file)
13641361
else:
1365-
logging.error(input_file + ': Unknown file suffix when compiling to LLVM bitcode!')
1366-
sys.exit(1)
1362+
exit_with_error(input_file + ': Unknown file suffix when compiling to LLVM bitcode!')
13671363

13681364
# exit block 'bitcodeize inputs'
13691365
log_time('bitcodeize inputs')
@@ -2129,8 +2125,7 @@ def parse_args(newargs):
21292125
elif newargs[i+1].lower() == 'linux':
21302126
options.output_eol = '\n'
21312127
else:
2132-
logging.error('Invalid value "' + newargs[i+1] + '" to --output_eol!')
2133-
exit(1)
2128+
exit_with_error('Invalid value "' + newargs[i+1] + '" to --output_eol!')
21342129
newargs[i] = ''
21352130
newargs[i+1] = ''
21362131

@@ -2230,8 +2225,7 @@ def binaryen_method_sanity_check():
22302225
valid_methods = ['asmjs', 'native-wasm', 'interpret-s-expr', 'interpret-binary', 'interpret-asm2wasm']
22312226
for m in methods:
22322227
if m.strip() not in valid_methods:
2233-
logging.error('Unrecognized BINARYEN_METHOD "' + m.strip() + '" specified! Please pass a comma-delimited list containing one or more of: ' + ','.join(valid_methods))
2234-
sys.exit(1)
2228+
exit_with_error('Unrecognized BINARYEN_METHOD "' + m.strip() + '" specified! Please pass a comma-delimited list containing one or more of: ' + ','.join(valid_methods))
22352229

22362230

22372231
def do_binaryen(final, target, asm_target, options, memfile, wasm_binary_target,
@@ -2266,8 +2260,7 @@ def do_binaryen(final, target, asm_target, options, memfile, wasm_binary_target,
22662260
if shared.Settings.BINARYEN_TRAP_MODE in ('js', 'clamp', 'allow'):
22672261
cmd += ['--trap-mode=' + shared.Settings.BINARYEN_TRAP_MODE]
22682262
else:
2269-
logging.error('invalid BINARYEN_TRAP_MODE value: ' + shared.Settings.BINARYEN_TRAP_MODE + ' (should be js/clamp/allow)')
2270-
sys.exit(1)
2263+
exit_with_error('invalid BINARYEN_TRAP_MODE value: ' + shared.Settings.BINARYEN_TRAP_MODE + ' (should be js/clamp/allow)')
22712264
if shared.Settings.BINARYEN_IGNORE_IMPLICIT_TRAPS:
22722265
cmd += ['--ignore-implicit-traps']
22732266
# pass optimization level to asm2wasm (if not optimizing, or which passes we should run was overridden, do not optimize)
@@ -2292,6 +2285,8 @@ def do_binaryen(final, target, asm_target, options, memfile, wasm_binary_target,
22922285
cmd += ['--no-legalize-javascript-ffi']
22932286
if shared.Building.is_wasm_only():
22942287
cmd += ['--wasm-only'] # this asm.js is code not intended to run as asm.js, it is only ever going to be wasm, an can contain special fastcomp-wasm support
2288+
if shared.Settings.USE_PTHREADS:
2289+
cmd += ['--enable-threads']
22952290
if debug_info:
22962291
cmd += ['-g']
22972292
if options.emit_symbol_map or shared.Settings.CYBERDWARF:

src/library_pthread.js

+5
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,12 @@ var LibraryPThread = {
366366
// object in Module['mainScriptUrlOrBlob'], or a URL to it, so that pthread Workers can
367367
// independently load up the same main application file.
368368
urlOrBlob: Module['mainScriptUrlOrBlob'] || currentScriptUrl,
369+
#if BINARYEN
370+
wasmMemory: Module['wasmMemory'],
371+
wasmModule: Module['wasmModule'],
372+
#else
369373
buffer: HEAPU8.buffer,
374+
#endif
370375
tempDoublePtr: tempDoublePtr,
371376
TOTAL_MEMORY: TOTAL_MEMORY,
372377
STATICTOP: STATICTOP,

src/preamble.js

+34-9
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,7 @@ if (typeof SharedArrayBuffer === 'undefined' || typeof Atomics === 'undefined')
11181118
#endif
11191119

11201120
#if USE_PTHREADS
1121+
#if !BINARYEN
11211122
if (typeof SharedArrayBuffer !== 'undefined') {
11221123
if (!ENVIRONMENT_IS_PTHREAD) buffer = new SharedArrayBuffer(TOTAL_MEMORY);
11231124
// Currently SharedArrayBuffer does not have a slice() operation, so polyfill it in.
@@ -1170,6 +1171,18 @@ if (typeof Atomics === 'undefined') {
11701171
Atomics['xor'] = function(t, i, v) { var w = t[i]; t[i] ^= v; return w; }
11711172
}
11721173

1174+
#else
1175+
if (!ENVIRONMENT_IS_PTHREAD) {
1176+
#if ALLOW_MEMORY_GROWTH
1177+
Module['wasmMemory'] = new WebAssembly.Memory({ 'initial': TOTAL_MEMORY / WASM_PAGE_SIZE , 'maximum': {{{ WASM_MEM_MAX }}} / WASM_PAGE_SIZE, 'shared': true });
1178+
#else
1179+
Module['wasmMemory'] = new WebAssembly.Memory({ 'initial': TOTAL_MEMORY / WASM_PAGE_SIZE , 'maximum': TOTAL_MEMORY / WASM_PAGE_SIZE, 'shared': true });
1180+
#endif
1181+
buffer = Module['wasmMemory'].buffer;
1182+
}
1183+
1184+
updateGlobalBufferViews();
1185+
#endif // !BINARYEN
11731186
#else // USE_PTHREADS
11741187

11751188
#if SPLIT_MEMORY == 0
@@ -1185,7 +1198,7 @@ if (Module['buffer']) {
11851198
if (typeof WebAssembly === 'object' && typeof WebAssembly.Memory === 'function') {
11861199
#if ASSERTIONS
11871200
assert(TOTAL_MEMORY % WASM_PAGE_SIZE === 0);
1188-
#endif
1201+
#endif // ASSERTIONS
11891202
#if ALLOW_MEMORY_GROWTH
11901203
#if WASM_MEM_MAX
11911204
#if ASSERTIONS
@@ -1194,19 +1207,19 @@ if (Module['buffer']) {
11941207
Module['wasmMemory'] = new WebAssembly.Memory({ 'initial': TOTAL_MEMORY / WASM_PAGE_SIZE, 'maximum': {{{ WASM_MEM_MAX }}} / WASM_PAGE_SIZE });
11951208
#else
11961209
Module['wasmMemory'] = new WebAssembly.Memory({ 'initial': TOTAL_MEMORY / WASM_PAGE_SIZE });
1197-
#endif
1210+
#endif // BINARYEN_MEM_MAX
11981211
#else
11991212
Module['wasmMemory'] = new WebAssembly.Memory({ 'initial': TOTAL_MEMORY / WASM_PAGE_SIZE, 'maximum': TOTAL_MEMORY / WASM_PAGE_SIZE });
1200-
#endif
1213+
#endif // ALLOW_MEMORY_GROWTH
12011214
buffer = Module['wasmMemory'].buffer;
12021215
} else
1203-
#endif
1216+
#endif // BINARYEN
12041217
{
12051218
buffer = new ArrayBuffer(TOTAL_MEMORY);
12061219
}
12071220
#if ASSERTIONS
12081221
assert(buffer.byteLength === TOTAL_MEMORY);
1209-
#endif
1222+
#endif // ASSERTIONS
12101223
}
12111224
updateGlobalBufferViews();
12121225
#else // SPLIT_MEMORY
@@ -2196,15 +2209,27 @@ function integrateWasmJS() {
21962209
info['env'] = env;
21972210
// handle a generated wasm instance, receiving its exports and
21982211
// performing other necessary setup
2199-
function receiveInstance(instance) {
2212+
function receiveInstance(instance, module) {
22002213
exports = instance.exports;
22012214
if (exports.memory) mergeMemory(exports.memory);
22022215
Module['asm'] = exports;
22032216
Module["usingWasm"] = true;
2217+
#if USE_PTHREADS
2218+
// Keep a reference to the compiled module so we can post it to the workers.
2219+
Module['wasmModule'] = module;
2220+
// Instantiation is synchronous in pthreads and we assert on run dependencies.
2221+
if(!ENVIRONMENT_IS_PTHREAD) removeRunDependency('wasm-instantiate');
2222+
#else
22042223
removeRunDependency('wasm-instantiate');
2224+
#endif
22052225
}
2206-
2207-
addRunDependency('wasm-instantiate'); // we can't run yet
2226+
#if USE_PTHREADS
2227+
if (!ENVIRONMENT_IS_PTHREAD) {
2228+
addRunDependency('wasm-instantiate'); // we can't run yet (except in a pthread, where we have a custom sync instantiator)
2229+
}
2230+
#else
2231+
addRunDependency('wasm-instantiate');
2232+
#endif
22082233

22092234
// User shell pages can write their own Module.instantiateWasm = function(imports, successCallback) callback
22102235
// to manually instantiate the Wasm module themselves. This allows pages to run the instantiation parallel
@@ -2235,7 +2260,7 @@ function integrateWasmJS() {
22352260
assert(Module === trueModule, 'the Module object should not be replaced during async compilation - perhaps the order of HTML elements is wrong?');
22362261
trueModule = null;
22372262
#endif
2238-
receiveInstance(output['instance']);
2263+
receiveInstance(output['instance'], output['module']);
22392264
}
22402265
function instantiateArrayBuffer(receiver) {
22412266
getBinaryPromise().then(function(binary) {

src/pthread-main.js

+25-1
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,43 @@ Module['print'] = threadPrint;
5454
Module['printErr'] = threadPrintErr;
5555
this.alert = threadAlert;
5656

57+
// #if WASM
58+
Module['instantiateWasm'] = function(info, receiveInstance) {
59+
// Instantiate from the module posted from the main thread.
60+
// We can just use sync instantiation in the worker.
61+
instance = new WebAssembly.Instance(Module['wasmModule'], info);
62+
// We don't need the module anymore; new threads will be spawned from the main thread.
63+
delete Module['wasmModule'];
64+
receiveInstance(instance);
65+
return instance.exports;
66+
}
67+
//#endif
68+
5769
this.onmessage = function(e) {
5870
try {
5971
if (e.data.cmd === 'load') { // Preload command that is called once per worker to parse and load the Emscripten code.
6072
// Initialize the thread-local field(s):
6173
tempDoublePtr = e.data.tempDoublePtr;
6274

6375
// Initialize the global "process"-wide fields:
64-
buffer = e.data.buffer;
6576
Module['TOTAL_MEMORY'] = TOTAL_MEMORY = e.data.TOTAL_MEMORY;
6677
STATICTOP = e.data.STATICTOP;
6778
DYNAMIC_BASE = e.data.DYNAMIC_BASE;
6879
DYNAMICTOP_PTR = e.data.DYNAMICTOP_PTR;
6980

81+
82+
//#if WASM
83+
if (e.data.wasmModule) {
84+
// Module and memory were sent from main thread
85+
Module['wasmModule'] = e.data.wasmModule;
86+
Module['wasmMemory'] = e.data.wasmMemory;
87+
buffer = Module['wasmMemory'].buffer;
88+
} else {
89+
//#else
90+
buffer = e.data.buffer;
91+
}
92+
//#endif
93+
7094
PthreadWorkerInit = e.data.PthreadWorkerInit;
7195
if (typeof e.data.urlOrBlob === 'string') {
7296
importScripts(e.data.urlOrBlob);

0 commit comments

Comments
 (0)