-
Notifications
You must be signed in to change notification settings - Fork 30.7k
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
esm: Source Phase Imports for WebAssembly #56919
base: main
Are you sure you want to change the base?
Conversation
Review requested:
|
c485531
to
8b3ce05
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #56919 +/- ##
==========================================
- Coverage 89.10% 89.09% -0.02%
==========================================
Files 665 665
Lines 193203 193400 +197
Branches 37220 37246 +26
==========================================
+ Hits 172158 172312 +154
- Misses 13771 13806 +35
- Partials 7274 7282 +8
|
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.
lgtm
* @param {ModuleWrap|ContextifyScript|Function|vm.Module} callbackReferrer | ||
* @param {Record<string, string>} attributes | ||
* @param {string} phase | ||
* @returns { Promise<void> } |
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.
Is this return value type correct? I think it should be Promise<ModuleNamespace|vm.Module>
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.
No it's not - but this is a move of an existing definition, so this is as it's currently written on main.
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.
Unless we never want to fix it, we should probably fix it on main
first, then move it in this PR
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.
Co-authored-by: Antoine du Hamel <duhamelantoine1995@gmail.com> Co-authored-by: Michaël Zasso <targos@protonmail.com>
6364566
to
98b0d48
Compare
This reverts commit 009373d.
@@ -607,8 +623,7 @@ void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) { | |||
} | |||
|
|||
if (try_catch.HasCaught()) { | |||
if (!try_catch.HasTerminated()) | |||
try_catch.ReThrow(); | |||
if (!try_catch.HasTerminated()) try_catch.ReThrow(); |
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 looks like an unrelated change that's going to make backporting stuff needlessly harder, could we get rid of it?
USE(module->InstantiateModule( | ||
context, ResolveModuleCallback, ResolveSourceCallback)); |
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.
Same here
USE(module->InstantiateModule( | ||
context, ResolveModuleCallback, ResolveSourceCallback)); |
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.
Same here
@@ -551,7 +567,7 @@ void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) { | |||
ContextifyContext* contextify_context = obj->contextify_context_; | |||
MicrotaskQueue* microtask_queue = nullptr; | |||
if (contextify_context != nullptr) | |||
microtask_queue = contextify_context->microtask_queue(); | |||
microtask_queue = contextify_context->microtask_queue(); |
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.
Same here
if (import_callback | ||
->Call( | ||
context, Undefined(isolate), arraysize(import_args), import_args) | ||
.ToLocal(&result)) { |
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.
Same here
Environment* env = Environment::GetCurrent(context); | ||
if (env == nullptr) | ||
return; | ||
if (env == nullptr) return; |
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.
Same here
obj->object()->SetInternalField(kSyntheticEvaluationStepsSlot, | ||
Undefined(isolate)); | ||
MaybeLocal<Value> ret = | ||
synthetic_evaluation_steps->Call(context, obj->object(), 0, nullptr); |
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.
Same here
'--eval', | ||
[ | ||
'import { strictEqual } from "node:assert";', | ||
`import * as wasmExports from ${JSON.stringify(fixtures.fileURL('es-modules/wasm-source-phase.js'))};`, |
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.
Drive-by; shouldn't this say import source * as wasmExports
?
'import { strictEqual } from "node:assert";', | ||
`import source mod from ${JSON.stringify(fixtures.fileURL('es-modules/unimportable.wasm'))};`, | ||
'assert.strictEqual(mod instanceof WebAssembly.Module, true);', |
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.
Also a question here - how does this test ensures that the import is not executed?
I'm working on corresponding patch to emscripten to enable source phase imports: emscripten-core/emscripten#23175 As such, I would love to see this patch landed so we can start testing it! |
This implements the Stage 3 Source Phase Imports proposal for Node.js (with latest specification at tc39/ecma262#3492), based on the new V8 parser and module loading APIs for this feature.
Phases in the module pipeline represent the ability to load uninstantiated modules (and in future with import defer, unexecuted modules as well).
While we are still waiting for progression on https://github.com/tc39/proposal-esm-phase-imports for JS Source Phase objects, this implements only the WebAssembly source phase per the Wasm ESM Integration Phase 3 proposal (https://github.com/webassembly/esm-integration).
This PR adds support both for dynamic and static source phase syntax:
This allows obtaining a Wasm module through the ESM integration, without it being instantiated through the Node.js resolver, to permit custom instantiations:
The dynamic source phase support is a one-line TODO, which is pending #56842. When this lands the skipped tests have been tested against that branch to fully pass.
When a source phase representation for a module is not available, a new
ERR_SOURCE_PHASE_NOT_DEFINED
SyntaxError is thrown as per the standard.The VM API is updated to take a string phase argument as its last argument, although the ability to define source phase representations for virtual modules is not currently supported, and left as a future integration point. Perhaps this will simplify with ESM Phase Imports in future as well allowing handles to modules outside of the VM graph.
Resolves #53178.
@nodejs/loaders