diff --git a/src/parseTools.mjs b/src/parseTools.mjs index 0a9fb43b14b2e..5dd2d9f644b09 100644 --- a/src/parseTools.mjs +++ b/src/parseTools.mjs @@ -1042,9 +1042,11 @@ function getUnsharedTextDecoderView(heap, start, end) { // then unconditionally do a .slice() for smallest code size. if (SHRINK_LEVEL == 2 || heap == 'HEAPU8') return shared; - // Otherwise, generate a runtime type check: must do a .slice() if looking at a SAB, - // or can use .subarray() otherwise. - return `${heap}.buffer instanceof SharedArrayBuffer ? ${shared} : ${unshared}`; + // Otherwise, generate a runtime type check: must do a .slice() if looking at + // a SAB, or can use .subarray() otherwise. Note: We compare with + // `ArrayBuffer` here to avoid referencing `SharedArrayBuffer` which could be + // undefined. + return `${heap}.buffer instanceof ArrayBuffer ? ${unshared} : ${shared}`; } function getEntryFunction() { diff --git a/test/test_other.py b/test/test_other.py index 32baf47b75dd4..f6307f9c2336c 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -12193,14 +12193,26 @@ def test_pthread_relocatable(self): @node_pthreads def test_pthread_unavailable(self): # Run a simple hello world program that uses pthreads - self.emcc_args += ['-sPROXY_TO_PTHREAD', '-sEXIT_RUNTIME'] + self.emcc_args += ['-sPROXY_TO_PTHREAD', '-sEXIT_RUNTIME', '-sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=$stringToNewUTF8,$UTF8ToString'] self.do_run_in_out_file_test('hello_world.c') # Now run the same program but with SharedArrayBuffer undefined, it should run # fine and then fail on the first call to pthread_create. - create_file('pre.js', 'SharedArrayBuffer = undefined\n') - expected = 'pthread_create: environment does not support SharedArrayBuffer, pthreads are not available' - self.do_runf('hello_world.c', expected, assert_returncode=NON_ZERO, emcc_args=['--pre-js=pre.js']) + # + # We specifically test that we can call UTF8ToString, which in older emscripten + # versions had an instanceof check against SharedArrayBuffer which would cause + # a crash when SharedArrayBuffer was undefined. + create_file('pre.js', ''' + SharedArrayBuffer = undefined; + Module.onRuntimeInitialized = () => { + var addr = stringToNewUTF8("hello world string, longer than 16 chars"); + assert(addr); + var str = UTF8ToString(addr); + console.log("got: " + str); + assert(str == "hello world string, longer than 16 chars"); + };''') + expected = ['got: hello world string, longer than 16 chars', 'pthread_create: environment does not support SharedArrayBuffer, pthreads are not available'] + self.do_runf('hello_world.c', expected, assert_all=True, assert_returncode=NON_ZERO, emcc_args=['--pre-js=pre.js']) def test_stdin_preprocess(self): create_file('temp.h', '#include ')