Skip to content

Commit ca8fd33

Browse files
authored
Fix data address exports under -sMAIN_MODULE=1 (#23020)
In `-sMAIN_MODULE=1` mode we actually link twice, once to get the names the user exported symbols then again with everything exported. We when use the this `base_metadata` to limit the things that we export to on the JS module. However for data symbols we cannot use the addresses/values present in `base_metadata`. Fixes: #22980
1 parent fe2744d commit ca8fd33

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

test/test_core.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4435,6 +4435,27 @@ def test_dylink_global_var(self):
44354435
int x = 123;
44364436
''', expected=['extern is 123.\n'], force_c=True)
44374437

4438+
@needs_dylink
4439+
def test_dylink_global_var_export(self):
4440+
self.do_run(r'''
4441+
#include <assert.h>
4442+
#include <stdio.h>
4443+
#include <emscripten.h>
4444+
#include <emscripten/em_asm.h>
4445+
4446+
EMSCRIPTEN_KEEPALIVE int my_number = 123456;
4447+
4448+
int main(void) {
4449+
void* js_address = EM_ASM_PTR({
4450+
console.log("JS:_my_number:", _my_number, HEAP32[_my_number/4]);
4451+
return _my_number;
4452+
});
4453+
printf("C: my_number: %ld %d\n", (long)&my_number, my_number);
4454+
assert(js_address == &my_number);
4455+
return 0;
4456+
}
4457+
''', emcc_args=['-sMAIN_MODULE'], force_c=True)
4458+
44384459
@with_dylink_reversed
44394460
def test_dylink_global_var_modded(self):
44404461
self.dylink_test(main=r'''

tools/emscripten.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,9 @@ def emscript(in_wasm, out_wasm, outfile_js, js_syms, finalize=True, base_metadat
441441

442442
if base_metadata:
443443
function_exports = base_metadata.function_exports
444-
global_exports = base_metadata.global_exports
444+
# We want the real values from the final metadata but we only want to
445+
# include names from the base_metadata. See phase_link() in link.py.
446+
global_exports = {k: v for k, v in metadata.global_exports.items() if k in base_metadata.global_exports}
445447
else:
446448
function_exports = metadata.function_exports
447449
global_exports = metadata.global_exports

0 commit comments

Comments
 (0)