diff --git a/system/lib/compiler-rt/stack_limits.S b/system/lib/compiler-rt/stack_limits.S index 1c4c719fa18af..d6906fe61ab71 100644 --- a/system/lib/compiler-rt/stack_limits.S +++ b/system/lib/compiler-rt/stack_limits.S @@ -15,6 +15,7 @@ #endif .globaltype __stack_pointer, PTR +.globl __stack_pointer .section .globals,"",@ @@ -22,7 +23,9 @@ # using PTR.const rather than using the `emscripten_stack_init` .globaltype __stack_end, PTR __stack_end: +.globl __stack_end .globaltype __stack_base, PTR +.globl __stack_base __stack_base: .section .text,"",@ @@ -82,57 +85,6 @@ emscripten_stack_get_free: PTR.sub end_function -#ifdef __EMSCRIPTEN_WASM_WORKERS__ -# TODO: Relocate the following to its own file wasm_worker.S, but need to figure out how to reference -# __stack_base and __stack_end globals from a separate file as externs in order for that to work. -.globl _emscripten_wasm_worker_initialize -_emscripten_wasm_worker_initialize: - .functype _emscripten_wasm_worker_initialize (PTR /*stackLowestAddress*/, i32 /*stackSize*/) -> () - - // __stack_end = stackLowestAddress + (__builtin_wasm_tls_size() + 15) & -16; - local.get 0 - .globaltype __tls_size, PTR, immutable - global.get __tls_size - PTR.add - PTR.const 0xf - PTR.add - PTR.const -0x10 - PTR.and - global.set __stack_end - - // __stack_base = stackLowestAddress + stackSize; - local.get 0 - local.get 1 -#ifdef __wasm64__ - i64.extend_i32_u -#endif - PTR.add - global.set __stack_base - -// TODO: We'd like to do this here to avoid JS side calls to __set_stack_limits. -// (or even better, we'd like to avoid duplicate versions of the stack variables) -// See https://github.com/emscripten-core/emscripten/issues/16496 -// global.get __stack_base -// global.get __stack_end -// .functype __set_stack_limits (PTR, PTR) -> () -// call __set_stack_limits - - // __wasm_init_tls(stackLowestAddress); - local.get 0 - .functype __wasm_init_tls (PTR) -> () - call __wasm_init_tls - - // N.b. The function __wasm_init_tls above does not need - // __stack_pointer initialized, and it destroys the value it was set to. - // So we must initialize __stack_pointer only *after* completing __wasm_init_tls: - - // __stack_pointer = __stack_base; - global.get __stack_base - global.set __stack_pointer - - end_function -#endif - # Add emscripten_stack_init to static ctors .section .init_array.1,"",@ .p2align ALIGN diff --git a/system/lib/dlmalloc.c b/system/lib/dlmalloc.c index 68fbe7f332756..f55ff649cfefb 100644 --- a/system/lib/dlmalloc.c +++ b/system/lib/dlmalloc.c @@ -21,13 +21,12 @@ /* XXX Emscripten Tracing API. This defines away the code if tracing is disabled. */ #include -#ifdef __EMSCRIPTEN_WASM_WORKERS__ +#ifdef __EMSCRIPTEN_SHARED_MEMORY__ #define USE_LOCKS 1 #endif /* Make malloc() and free() threadsafe by securing the memory allocations with pthread mutexes. */ #if __EMSCRIPTEN_PTHREADS__ -#define USE_LOCKS 1 #define USE_SPIN_LOCKS 0 // Ensure we use pthread_mutex_t. #endif diff --git a/system/lib/wasm_worker/wasm_worker_initialize.S b/system/lib/wasm_worker/wasm_worker_initialize.S new file mode 100644 index 0000000000000..8e144158a3f82 --- /dev/null +++ b/system/lib/wasm_worker/wasm_worker_initialize.S @@ -0,0 +1,64 @@ +.extern __stack_pointer +.extern __stack_base +.extern __stack_end + +#ifdef __wasm64__ +#define PTR i64 +#define ALIGN 3 +#define PTRSTORE .int64 +#else +#define PTR i32 +#define ALIGN 2 +#define PTRSTORE .int32 +#endif + +.globaltype __stack_pointer, PTR +.globaltype __stack_end, PTR +.globaltype __stack_base, PTR + +.globl _emscripten_wasm_worker_initialize +_emscripten_wasm_worker_initialize: + .functype _emscripten_wasm_worker_initialize (PTR /*stackLowestAddress*/, i32 /*stackSize*/) -> () + + // __stack_end = stackLowestAddress + (__builtin_wasm_tls_size() + 15) & -16; + local.get 0 + .globaltype __tls_size, PTR, immutable + global.get __tls_size + PTR.add + PTR.const 0xf + PTR.add + PTR.const -0x10 + PTR.and + global.set __stack_end + + // __stack_base = stackLowestAddress + stackSize; + local.get 0 + local.get 1 +#ifdef __wasm64__ + i64.extend_i32_u +#endif + PTR.add + global.set __stack_base + +// TODO: We'd like to do this here to avoid JS side calls to __set_stack_limits. +// (or even better, we'd like to avoid duplicate versions of the stack variables) +// See https://github.com/emscripten-core/emscripten/issues/16496 +// global.get __stack_base +// global.get __stack_end +// .functype __set_stack_limits (PTR, PTR) -> () +// call __set_stack_limits + + // __wasm_init_tls(stackLowestAddress); + local.get 0 + .functype __wasm_init_tls (PTR) -> () + call __wasm_init_tls + + // N.b. The function __wasm_init_tls above does not need + // __stack_pointer initialized, and it destroys the value it was set to. + // So we must initialize __stack_pointer only *after* completing __wasm_init_tls: + + // __stack_pointer = __stack_base; + global.get __stack_base + global.set __stack_pointer + + end_function diff --git a/test/core/test_dlfcn_self.exports b/test/core/test_dlfcn_self.exports index 778003379ab0f..0017bb938a99b 100644 --- a/test/core/test_dlfcn_self.exports +++ b/test/core/test_dlfcn_self.exports @@ -9,7 +9,9 @@ __progname_full __sig_actions __sig_pending __signgam +__stack_base __stack_chk_guard +__stack_end __threwValue __timezone __tzname diff --git a/test/core/test_em_asm_unicode.out b/test/core/test_em_asm_unicode.out index 4ef53eab9a770..31caff8090468 100644 --- a/test/core/test_em_asm_unicode.out +++ b/test/core/test_em_asm_unicode.out @@ -1 +1 @@ -hello world… \ No newline at end of file +hello world… diff --git a/test/core/test_longjmp.out b/test/core/test_longjmp.out index 4a412fef09f74..e9cc75258d28d 100644 --- a/test/core/test_longjmp.out +++ b/test/core/test_longjmp.out @@ -1,4 +1,4 @@ first result: 1 1 second -result: 2 -1 \ No newline at end of file +result: 2 -1 diff --git a/tools/link.py b/tools/link.py index 22a8b7494fb04..44fee4acef50e 100644 --- a/tools/link.py +++ b/tools/link.py @@ -1413,7 +1413,7 @@ def phase_linker_setup(options, state, newargs): 'removeRunDependency', ] - if settings.SHARED_MEMORY or settings.RELOCATABLE or settings.ASYNCIFY_LAZY_LOAD_CODE: + if settings.PTHREADS or settings.WASM_WORKERS or settings.RELOCATABLE or settings.ASYNCIFY_LAZY_LOAD_CODE: settings.IMPORTED_MEMORY = 1 set_initial_memory() diff --git a/tools/system_libs.py b/tools/system_libs.py index c202d3770747a..13413638054d4 100644 --- a/tools/system_libs.py +++ b/tools/system_libs.py @@ -742,12 +742,17 @@ def vary_on(cls): @classmethod def get_default_variation(cls, **kwargs): - return super().get_default_variation(is_mt=settings.PTHREADS, is_ww=settings.WASM_WORKERS and not settings.PTHREADS, **kwargs) + return super().get_default_variation( + is_mt=settings.PTHREADS, + is_ww=settings.SHARED_MEMORY and not settings.PTHREADS, + **kwargs + ) @classmethod def variations(cls): combos = super(MTLibrary, cls).variations() - # To save on # of variations, pthreads and Wasm workers when used together, just use pthreads variation. + + # These are mutually exclusive, only one flag will be set at any give time. return [combo for combo in combos if not combo['is_mt'] or not combo['is_ww']] @@ -1452,9 +1457,19 @@ def get_default_variation(cls, **kwargs): return super().get_default_variation(stub=not settings.WASM_WORKERS, **kwargs) def get_files(self): + files = [] + if self.is_stub: + files = [ + 'library_wasm_worker_stub.c' + ] + else: + files = [ + 'library_wasm_worker.c', + 'wasm_worker_initialize.S', + ] return files_in_path( path='system/lib/wasm_worker', - filenames=['library_wasm_worker_stub.c' if self.is_stub else 'library_wasm_worker.c']) + filenames=files) def can_use(self): # see src/library_wasm_worker.js