Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/lib/libcore.js
Original file line number Diff line number Diff line change
Expand Up @@ -2402,7 +2402,12 @@ addToLibrary({
ATPOSTCTORS.unshift('callRuntimeCallbacks(onPostCtors);');
},
$addOnPostCtor__deps: ['$onPostCtors'],
$addOnPostCtor: (cb) => onPostCtors.push(cb),
$addOnPostCtor: (cb) => {
#if ASSERTIONS
assert(!runtimeInitialized, 'addOnPostCtor called too late: ctors have already run');
#endif
onPostCtors.push(cb);
},
// See ATMAINS in parseTools.mjs for more information.
$onMains: [],
$onMains__internal: true,
Expand Down
5 changes: 5 additions & 0 deletions src/postamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,11 @@ var wasmRawExports;
#endif

#if MODULARIZE == 'instance'
#if EMBIND_AOT
// The embind exports are declared here so that their post-ctor registration
// precedes any self-initialization below. See phase_embind_aot in link.py.
<<< EMBIND_AOT_EXPORTS >>>
#endif
// In MODULARIZE=instance mode we delay most of the initialization work until
// the `init` function is called.
#if ASSERTIONS
Expand Down
19 changes: 19 additions & 0 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -6273,6 +6273,25 @@ def test_modularize_instance_auto_init(self):

self.assertContained('main1\nmain2\nfoo\nbar\nbaz\n', self.run_js('runner.mjs'))

def test_modularize_instance_auto_init_embind(self):
# Embind exports must be assigned when the module self-initializes on
# import. See https://github.com/emscripten-core/emscripten/issues/27411
self.run_process([EMXX, test_file('modularize_instance_embind.cpp'),
'-sMODULARIZE=instance', '-sAUTO_INIT',
'-Wno-experimental',
'-lembind', '-sEMBIND_AOT',
'-o', 'modularize_instance_embind.mjs'] + self.get_cflags())

create_file('runner.mjs', '''
import { foo, Bar } from "./modularize_instance_embind.mjs";
foo();
const bar = new Bar();
bar.print();
bar.delete();
''')

self.assertContained('main\nfoo\nbar\n', self.run_js('runner.mjs'))

@also_with_pthreads
@requires_node_25
def test_esm_integration_auto_init(self):
Expand Down
2 changes: 1 addition & 1 deletion tools/link.py
Original file line number Diff line number Diff line change
Expand Up @@ -2126,7 +2126,7 @@ def phase_embind_aot(options, wasm_target, js_syms):
addOnPostCtor(assignEmbindExports);
{decls}
// end embind exports'''
src += exports
src = do_replace(src, '<<< EMBIND_AOT_EXPORTS >>>', exports)
write_file(final_js, src)
if settings.WASM_ESM_INTEGRATION:
# With ESM integration the embind exports also need to be exported by the main file.
Expand Down
Loading