From ec2dce70cec9d362cac87890c4f396bcc52dbc98 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Sun, 28 Sep 2025 21:52:53 -0700 Subject: [PATCH] Use createNamedFunction in the dynamic linker This helps with debugging since the runtime-generated functions show up in backtraces with meaningful names. --- src/lib/libcore.js | 4 ++++ src/lib/libdylink.js | 8 ++++---- src/lib/libembind.js | 2 -- src/lib/libembind_gen.js | 1 - test/codesize/test_codesize_hello_O0.json | 8 ++++---- test/codesize/test_codesize_hello_dylink.json | 8 ++++---- test/codesize/test_codesize_hello_dylink_all.json | 4 ++-- test/codesize/test_codesize_minimal_O0.expected.js | 1 + test/codesize/test_codesize_minimal_O0.json | 8 ++++---- test/codesize/test_unoptimized_code_size.json | 12 ++++++------ 10 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/lib/libcore.js b/src/lib/libcore.js index 25b91739a845e..3c11245c7674a 100644 --- a/src/lib/libcore.js +++ b/src/lib/libcore.js @@ -41,6 +41,10 @@ addToLibrary({ setTempRet0: '$setTempRet0', getTempRet0: '$getTempRet0', + // Assign a name to a given function. This is mostly useful for debugging + // purposes in cases where new functions are created at runtime. + $createNamedFunction: (name, func) => Object.defineProperty(func, 'name', { value: name }), + $ptrToString: (ptr) => { #if ASSERTIONS assert(typeof ptr === 'number', `ptrToString expects a number, got ${typeof ptr}`); diff --git a/src/lib/libdylink.js b/src/lib/libdylink.js index c23c247de3fcf..a0e19f63197c0 100644 --- a/src/lib/libdylink.js +++ b/src/lib/libdylink.js @@ -116,7 +116,7 @@ var LibraryDylink = { // the canonical name of the symbol (in some cases is modify the symbol as // part of the loop process, so that actual symbol looked up has a different // name). - $resolveGlobalSymbol__deps: ['$isSymbolDefined', + $resolveGlobalSymbol__deps: ['$isSymbolDefined', '$createNamedFunction', #if !DISABLE_EXCEPTION_CATCHING || SUPPORT_LONGJMP == 'emscripten' '$createInvokeFunction', #endif @@ -138,7 +138,7 @@ var LibraryDylink = { // Asm.js-style exception handling: invoke wrapper generation else if (symName.startsWith('invoke_')) { // Create (and cache) new invoke_ functions on demand. - sym = wasmImports[symName] = createInvokeFunction(symName.split('_')[1]); + sym = wasmImports[symName] = createNamedFunction(symName, createInvokeFunction(symName.split('_')[1])); } #endif #if !DISABLE_EXCEPTION_CATCHING @@ -147,13 +147,13 @@ var LibraryDylink = { // `__cxa_find_matching_catch_` (see jsifier.js) that we know are needed, // but a side module loaded at runtime might need different/additional // variants so we create those dynamically. - sym = wasmImports[symName] = (...args) => { + sym = wasmImports[symName] = createNamedFunction(symName, (...args) => { #if MEMORY64 args = args.map(Number); #endif var rtn = findMatchingCatch(args); return {{{ to64('rtn') }}}; - } + }); } #endif return {sym, name: symName}; diff --git a/src/lib/libembind.js b/src/lib/libembind.js index e76f744a525a6..73fc8388ac3ae 100644 --- a/src/lib/libembind.js +++ b/src/lib/libembind.js @@ -122,8 +122,6 @@ var LibraryEmbind = { } }, - $createNamedFunction: (name, func) => Object.defineProperty(func, 'name', { value: name }), - $embindRepr: (v) => { if (v === null) { return 'null'; diff --git a/src/lib/libembind_gen.js b/src/lib/libembind_gen.js index dba7bcb992681..050fa4d7a77de 100644 --- a/src/lib/libembind_gen.js +++ b/src/lib/libembind_gen.js @@ -870,7 +870,6 @@ var LibraryEmbind = { // Stub functions used by eval, but not needed for TS generation: $makeLegalFunctionName: () => { throw new Error('stub function should not be called'); }, $runDestructors: () => { throw new Error('stub function should not be called'); }, - $createNamedFunction: () => { throw new Error('stub function should not be called'); }, $flushPendingDeletes: () => { throw new Error('stub function should not be called'); }, $setDelayFunction: () => { throw new Error('stub function should not be called'); }, $PureVirtualError: () => { throw new Error('stub function should not be called'); }, diff --git a/test/codesize/test_codesize_hello_O0.json b/test/codesize/test_codesize_hello_O0.json index dd279d10cb892..b09c2d65fca45 100644 --- a/test/codesize/test_codesize_hello_O0.json +++ b/test/codesize/test_codesize_hello_O0.json @@ -1,10 +1,10 @@ { - "a.out.js": 22458, - "a.out.js.gz": 8308, + "a.out.js": 22478, + "a.out.js.gz": 8314, "a.out.nodebug.wasm": 15127, "a.out.nodebug.wasm.gz": 7450, - "total": 37585, - "total_gz": 15758, + "total": 37605, + "total_gz": 15764, "sent": [ "fd_write" ], diff --git a/test/codesize/test_codesize_hello_dylink.json b/test/codesize/test_codesize_hello_dylink.json index 8e234836ee9e3..d45d4492cefb0 100644 --- a/test/codesize/test_codesize_hello_dylink.json +++ b/test/codesize/test_codesize_hello_dylink.json @@ -1,10 +1,10 @@ { - "a.out.js": 26946, - "a.out.js.gz": 11478, + "a.out.js": 26985, + "a.out.js.gz": 11495, "a.out.nodebug.wasm": 18567, "a.out.nodebug.wasm.gz": 9199, - "total": 45513, - "total_gz": 20677, + "total": 45552, + "total_gz": 20694, "sent": [ "__heap_base", "__indirect_function_table", diff --git a/test/codesize/test_codesize_hello_dylink_all.json b/test/codesize/test_codesize_hello_dylink_all.json index d86b830fc46af..7c4486161a4ea 100644 --- a/test/codesize/test_codesize_hello_dylink_all.json +++ b/test/codesize/test_codesize_hello_dylink_all.json @@ -1,7 +1,7 @@ { - "a.out.js": 245989, + "a.out.js": 246028, "a.out.nodebug.wasm": 597755, - "total": 843744, + "total": 843783, "sent": [ "IMG_Init", "IMG_Load", diff --git a/test/codesize/test_codesize_minimal_O0.expected.js b/test/codesize/test_codesize_minimal_O0.expected.js index 0baf783f1f58b..7b292eb37b73b 100644 --- a/test/codesize/test_codesize_minimal_O0.expected.js +++ b/test/codesize/test_codesize_minimal_O0.expected.js @@ -877,6 +877,7 @@ Module['FS_createPreloadedFile'] = FS.createPreloadedFile; 'stackAlloc', 'getTempRet0', 'setTempRet0', + 'createNamedFunction', 'zeroMemory', 'exitJS', 'getHeapMax', diff --git a/test/codesize/test_codesize_minimal_O0.json b/test/codesize/test_codesize_minimal_O0.json index 5b4f79b68af7d..5bd6b948c0392 100644 --- a/test/codesize/test_codesize_minimal_O0.json +++ b/test/codesize/test_codesize_minimal_O0.json @@ -1,10 +1,10 @@ { - "a.out.js": 17734, - "a.out.js.gz": 6610, + "a.out.js": 17754, + "a.out.js.gz": 6617, "a.out.nodebug.wasm": 1136, "a.out.nodebug.wasm.gz": 659, - "total": 18870, - "total_gz": 7269, + "total": 18890, + "total_gz": 7276, "sent": [], "imports": [], "exports": [ diff --git a/test/codesize/test_unoptimized_code_size.json b/test/codesize/test_unoptimized_code_size.json index 0efbdde318eca..7dd706946a63e 100644 --- a/test/codesize/test_unoptimized_code_size.json +++ b/test/codesize/test_unoptimized_code_size.json @@ -1,16 +1,16 @@ { - "hello_world.js": 54108, - "hello_world.js.gz": 17086, + "hello_world.js": 54133, + "hello_world.js.gz": 17091, "hello_world.wasm": 15127, "hello_world.wasm.gz": 7450, "no_asserts.js": 26513, "no_asserts.js.gz": 8864, "no_asserts.wasm": 12227, "no_asserts.wasm.gz": 6010, - "strict.js": 52146, - "strict.js.gz": 16420, + "strict.js": 52171, + "strict.js.gz": 16426, "strict.wasm": 15127, "strict.wasm.gz": 7447, - "total": 175248, - "total_gz": 63277 + "total": 175298, + "total_gz": 63288 }