-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make 'instantiateWasm' callback resolve the result return from 'recei… #23781
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tanks for the fix!
Do you think we can update one of the existing tests to cover this? Maybe test_instantiate_wasm
in test_other.py
I have just updated the test unit. And this issue only affects when EXPORT_ES6 enabled. When EXPORT_ES6 disabled. createWasm called after wasmExports defined. var wasmExports;
createWasm(); wasmExports can be updated in createWasm. When EXPORT_ES6 enabled. wasmExports assigned by the return value of createWasm. var wasmExports = await createWasm(); |
assert(result); | ||
printf("main: before getResult\n"); | ||
int result = getResult(); | ||
printf("testWasmInstantiationSucceeded: %d\n",result); | ||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are the changes in this file necessary? It looks like you could revert this file probably.
test/test_other.py
Outdated
@@ -15688,7 +15688,12 @@ def test_instantiate_wasm(self): | |||
}); | |||
return {}; // Compiling asynchronously, no exports. | |||
}''') | |||
self.do_runf('test_manual_wasm_instantiate.c', emcc_args=['--pre-js=pre.js']) | |||
self.run_process([EMCC, test_file('test_manual_wasm_instantiate.c'), '--pre-js=pre.js','-sASYNCIFY','-sEXPORT_ES6=1','-o','manual_init_module.mjs']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need to add '-sASYNCIFY' here do you?
test/test_other.py
Outdated
@@ -15688,7 +15688,12 @@ def test_instantiate_wasm(self): | |||
}); | |||
return {}; // Compiling asynchronously, no exports. | |||
}''') | |||
self.do_runf('test_manual_wasm_instantiate.c', emcc_args=['--pre-js=pre.js']) | |||
self.run_process([EMCC, test_file('test_manual_wasm_instantiate.c'), '--pre-js=pre.js','-sASYNCIFY','-sEXPORT_ES6=1','-o','manual_init_module.mjs']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test is already decorated with also_with_modularize
so it should already run both with and without -sMODULARIZE
.
Do this bug depened on -sEXPORT_ES6
, no just -sMODULARIZE
somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did I misunderstand it? I need to add a new test unit to cover this situation not edit existing one.
This bug just depened on -sASYNCIFY and -sEXPORT_ES6.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see.. the bug only occurs with -sEXPORT_ES6
.
I don't see how it depends on -sASYNCIFY
though, maybe that flag can be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I think I understand now. -sASYNCIFY
is needed because in that mode we wrap the wasm exports.
However, I think -sMODULARIZE
should be enough (no need for -sEXPORT_ES6
). So I think if you run test_instantiate_wasm_modularize
(the modularized version) with -sASYNCIFY
that should be enough to repro the issue without creating manual_init.mjs
.
Sorry for the confusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
source here.
Module['instantiateWasm'](info, (mod, inst) => {
// When -sASYNCIFY. This function will wrap the original exports and return.
receiveInstance(mod, inst);
// But here always resolve the original exports.
resolve(mod.exports);
});
And when EXPORT_ES6 enabled. wasmExports assigned by the return value of createWasm.
var wasmExports = await createWasm();
So the wasmExports will always be the original exports object. Not the wrapped one.
It will case crash when a C++ function rewind.
If -sASYNCIFY removed. It will always success. because:
var wasmExports;
// return value not used.
createWasm();
And source here updated the global wasmExports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And when EXPORT_ES6 enabled. wasmExports assigned by the return value of createWasm.
But this is also true for just -sMODULARIZE
. i.e. i think this bug will show up with either -sMODULARIZE
or -sEXPORT_ES6
.. so it should be enough to test with the existing test_instantiate_wasm_modularize
The test failures look like they are because |
When -sASYNCIFY added into test_manual_wasm_instantiate in test_browser.py. Then main function in test_manual_wasm_instantiate.c have to call REPORT_RESULT(0); and change reporting=Reporting.JS_ONLY to reporting=Reporting.FULL to report the result. But other.test_instantiate_wasm doesn't link report_result.c that will case compile failed. Please give me some advice. Do I need to create a separate .c file for browser.test_manual_wasm_instantiate? |
Hi, what is the status of this PR? -- |
Maybe adding a new test for this specific case wouldn’t be such a bad idea? |
I think its almost ready.. just needs the tests to pass. |
shutil.copy(test_file('test_manual_wasm_instantiate.html'), '.') | ||
self.run_browser('test_manual_wasm_instantiate.html', '/report_result?exit:0') | ||
self.run_browser('test_manual_wasm_instantiate.html', '/report_result?1') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this change needed?
In js output content.
When ASYNCIFY enabled, wasmExports modified by Asyncify.instrumentWasmExports. source
But when Module['instantiateWasm'] used. The createWasm function will always resolve the original wasmExports. source.
It will case crash when async C++ function rewind.
So I make instantiateWasm callback resolve the result return from receiveInstance.