Skip to content
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

Reviews for Stage 2.7 #26

Open
1 of 5 tasks
guybedford opened this issue Nov 14, 2024 · 10 comments
Open
1 of 5 tasks

Reviews for Stage 2.7 #26

guybedford opened this issue Nov 14, 2024 · 10 comments

Comments

@guybedford
Copy link
Collaborator

guybedford commented Nov 14, 2024

Issue to track Stage 2 reviewers feedback.

Spec: https://tc39.es/proposal-esm-phase-imports/

Reviewers:

Editors:

@ljharb
Copy link
Member

ljharb commented Nov 14, 2024

to clarify, reviewers are within stage 2, they're just a prerequisite for stage 2.7.

@guybedford guybedford changed the title Stage 2.7 Reviews Reviews for Stage 2.7 Nov 14, 2024
@michaelficarra
Copy link
Member

  1. EvaluateImportCall step 9.b.i: don't say "is not equal to", just say "is not"; see https://github.com/tc39/ecma262/wiki/Editorial-Conventions#comparisons.
  2. GetModuleSourceModuleRecord: wouldn't it be more appropriate to name this parameter specifier? Isn't it still conceptually a specifier?
  3. GetModuleSourceModuleRecord step 5: "is equal to" -> "is"
  4. Source Text Module Records [[SourceText]] field: "ECMAScript source text" is probably a better type. Also I wouldn't include the optimisation note for hosts.
  5. Source Text Module Records [[ModuleSource]] field: like the above rows, we should describe when it's expected to be empty
  6. ModuleSourcesEqual step 2: "is equal to" -> "is"
  7. The ModuleSource constructor: I don't think this is needed: "will throw an error when invoked, where support for dynamic construction may be added in future"
  8. Where is ModuleSourcesEqual called? Why is it on abstract module records and not just source text module records (or better yet, just an AO) if we know it'll only be called on them?
  9. "For Module Records that implement a normal completion" -> "For Module Records that return a normal completion"
  10. I don't love the not-a-source enum name, but we can bikeshed that during integration

@guybedford guybedford mentioned this issue Nov 22, 2024
8 tasks
@michaelficarra
Copy link
Member

LGTM

@syg
Copy link

syg commented Nov 25, 2024

My normative review:

  • Why does EvaluateImportCall get a ModuleSource without consulting the phase argument? That doesn't seem right. If it's intentional then I don't understand what step 9 is doing at all.

My editorial review:

  • This is layered on top of source phase imports but I don't see necessary changes needed to that spec draft (e.g. EvaluateImportCall callsites).
  • GetModuleSource Step 3, the call to OrdinaryObjectCreate needs to pass « [[SourceTextModuleRecord]] » as an additional internal slot
  • ModuleSourcesEqual is a weird AO; is it needed? It seems like it's only used by embedder specs? If so, can the embedder compare identity of the value in [[SourceText]] instead of calling this AO?

@guybedford
Copy link
Collaborator Author

Why does EvaluateImportCall get a ModuleSource without consulting the phase argument? That doesn't seem right. If it's intentional then I don't understand what step 9 is doing at all.

Will do my best to explain further, and happy to discuss more. The import(moduleSource) use case is the ability to import the module instance at the key of a module source.

This is the required primitive for module expressions since a module expression would allow both import(module { export var p = 5 }) and postMessage, while having its JS object representation be the module source object. In turn we would also enable import(wasmModule) with the same behaviour, and in particular for source-phase-imported Wasm.

The registry effectively consists of a key - (module source, module Instance) 1 - 1 "canonical" source / instance pair relation. We get the pair today since a module record just is both things. This is the phasing model - url -> source -> instance all building off the same registry key. Since the module source associates directly with its URL, this allows them to be used as a proxy for their canonical instance, hence being supported in dynamic import() in a well-defined way as an import capability for the module in a sense.

Supporting new Worker(modSource), postMessage(modSource) and import(modSource) in this proposal get us the basic primitives to then follow-up with the module harmony features from there, and including in the Wasm world the ability to have module handles as well. The most pressing next step right now though being module expressions and module declarations.

I can work on more clearly motivating the above if it would help. The module full primitive goal is a crucial one to get right here though, we have to solve all of representation, postMessage and registry identity together, it's no use solving one without the other.

This is layered on top of source phase imports but I don't see necessary changes needed to that spec draft (e.g. EvaluateImportCall callsites).

Can you clarify what you mean by this? The latest source phase spec it is based to is the one here - tc39/ecma262#3492, not the version in the spec repo, which is now out of date. Does that help?

GetModuleSource Step 3, the call to OrdinaryObjectCreate needs to pass « [[SourceTextModuleRecord]] » as an additional internal slot

Thanks, added in #39.

ModuleSourcesEqual is a weird AO; is it needed? It seems like it's only used by embedder specs? If so, can the embedder compare identity of the value in [[SourceText]] instead of calling this AO?

The benefit of defining this was that Wasm could define it in the same way for WebAssembly module records. I found myself writing this out in HTML explicitly, and it felt unnecessary there. Formally defining the meaning for equality for module sources needs to be done somewhere - either in HTML or ECMA-262. @michaelficarra also brought this one up though, maybe we should just cut it until it's needed to be called directly from ECMA-262 though?

@syg
Copy link

syg commented Nov 26, 2024

Oh I see, I completely misunderstood the use case then. I'll give it a second read tomorrow.

@nicolo-ribaudo
Copy link
Member

nicolo-ribaudo commented Nov 26, 2024

  1. In EvaluateImportCall step 9.b, I'd prefer to swap steps i and ii: first we "read" the arguments, and then we do validation.
  2. In EvaluateImportCall step 9.b.ii, we need to validate that options is an object before reading "with" from it. See steps 10.d.i.
  3. (Not really a review comment: I wish GetModuleSourceName of Source Text Modules could return "JavaScript Module Source")
  4. I don't understand the change in step 1 of FinishLoadingImportedModule. Why if we are importing a string specifier we don't want anymore to add it to the loaded map?

I finished going through the spec -- consider my review as ✔ when 1/2/4 are solved (or explicitly not).

@guybedford
Copy link
Collaborator Author

Added #40 for points 1 & 2 above.

For (3), yeah that's what we mean...

I don't understand the change in step 1 of FinishLoadingImportedModule. Why if we are importing a string specifier we don't want anymore to add it to the loaded map?

In the case where you do import(moduleSource) we can't add anything to the map, therefore we gate step one of FinishLoadingImportedModule on the module request being a string, and not a module source (which results in the module request being passed as a module record). That is, import(moduleSource) is a module request for a module record, not a module request record, and that is reflected in the types of HostLoadImportedModule and FinishLoadingImportedModule. Let me know if I'm missing something here though.

@syg
Copy link

syg commented Nov 26, 2024

Will do my best to explain further, and happy to discuss more. The import(moduleSource) use case is the ability to import the module instance at the key of a module source.

Thanks for the explanation, the use case makes sense to me.

Step 9.b.i of EvaluateImportCall doesn't seem to allow import(moduleSourceObj) where options is undefined. Is that intentional?

The latest source phase spec it is based to is the one here - tc39/ecma262#3492, not the version in the spec repo, which is now out of date. Does that help?

Ack. That helps and addresses my previous question.

With the explanation, editorially LGTM.

@guybedford
Copy link
Collaborator Author

Thanks, added #42.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants