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

Normative: Add JSON modules #3391

Open
wants to merge 1 commit into
base: import-attributes
Choose a base branch
from

Conversation

nicolo-ribaudo
Copy link
Member

This pull request builds on top of #3057.

I mostly ported the spec text as-is, taking care of integrating editorial changes from the PRs open in the repo, but I have a few comments / questions for the editors.


<emu-clause id="sec-createsyntheticmodule" type="abstract operation">
<h1>
CreateSyntheticModule (
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This AO is only used once, it's not used in any host spec, and its implementation is a single line. Can we inline it?

It seems like V8 has an API based on this AO (https://v8docs.nodesource.com/node-13.2/df/d74/classv8_1_1_module.html#aeaa8c3cfb75478b9403be3d3955bb338), but nothing prevents implementations to keep providing this sort of constructor for Synthetic Module Records.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I would inline this and remove the references to it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with inlining it.

spec.html Show resolved Hide resolved
</emu-clause>

<emu-clause id="sec-smr-module-record-methods">
<h1>Implementation of Module Record abstract methods</h1>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quoting a note from the original authors of the proposal:

I find having this wrapping sub-clause cleaner and suggest we do the same for Source Text Module Records in the main spec.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, they should match.


<p>The following are the concrete methods for Synthetic Module Record that implement the corresponding Module Record abstract methods defined in <emu-xref href="#table-abstract-methods-of-module-records"></emu-xref>.</p>

<emu-clause id="sec-smr-LoadRequestedModules" type="concrete method">
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an open PR in the proposal changing these smr shorthands to the longer sec-synthetic-module-record-LoadRequestedModules. What is the editorial preference?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am completely unopinionated on IDs. This ID is fine.

@nicolo-ribaudo nicolo-ribaudo added pending stage 4 This proposal has not yet achieved stage 4, but may otherwise be ready to merge. proposal This is related to a specific proposal, and will be closed/merged when the proposal reaches stage 4. labels Aug 14, 2024
@nicolo-ribaudo nicolo-ribaudo changed the title Add Import Attributes proposal Normative: Add JSON modules Aug 14, 2024
@nicolo-ribaudo nicolo-ribaudo added has test262 tests normative change Affects behavior required to correctly evaluate some ECMAScript source text labels Aug 14, 2024
</dl>

<emu-alg>
1. Let _json_ be ? Call(%JSON.parse%, *undefined*, « _source_ »).
Copy link
Member Author

@nicolo-ribaudo nicolo-ribaudo Aug 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should steps 2-9 of JSON.parse be extracted to a new AO that we can call here, or is this ok?

Related: #1012 and https://infra.spec.whatwg.org/#parse-a-json-string-to-a-javascript-value

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with either way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mildly prefer the AO (after #3394 lands), but that refactoring can happen after this PR.

@nicolo-ribaudo
Copy link
Member Author

nicolo-ribaudo commented Sep 24, 2024

@tc39/ecma262-editors Remember that this is going for stage 4 at the next meeting :)

@@ -28495,12 +28698,19 @@ <h1>
</ul>
<p>and it performs FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_) where _result_ is a normal completion, then it must perform FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_) with the same _result_ each time.</p>
</li>
<li>
<p>If _moduleRequest_.[[Attributes]] has an entry _entry_ such that _entry_.[[Key]] is *"type"* and _entry_.[[Value]] is *"json"*, the host environment must perform FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_), where _result_ is either the Completion Record returned by an invokation of ParseJSONModule or a throw completion.</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<p>If _moduleRequest_.[[Attributes]] has an entry _entry_ such that _entry_.[[Key]] is *"type"* and _entry_.[[Value]] is *"json"*, the host environment must perform FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_), where _result_ is either the Completion Record returned by an invokation of ParseJSONModule or a throw completion.</p>
<p>If _moduleRequest_.[[Attributes]] has an entry _entry_ such that _entry_.[[Key]] is *"type"* and _entry_.[[Value]] is *"json"*, the host environment must perform FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_), where _result_ is either the Completion Record returned by an invocation of ParseJSONModule or a throw completion.</p>

@nicolo-ribaudo nicolo-ribaudo added has stage 4 This PR represents a proposal that has achieved stage 4, and is ready to merge. and removed pending stage 4 This proposal has not yet achieved stage 4, but may otherwise be ready to merge. labels Oct 9, 2024
<li>
The operation must treat _payload_ as an opaque value to be passed through to FinishLoadingImportedModule.
</li>
</ul>

<p>The actual process performed is host-defined, but typically consists of performing whatever I/O operations are necessary to load the appropriate Module Record. Multiple different (_referrer_, _moduleRequest_.[[Specifier]], _moduleRequest_.[[Attributes]]) triples may map to the same Module Record instance. The actual mapping semantics is host-defined but typically a normalization process is applied to _specifier_ as part of the mapping process. A typical normalization process would include actions such as expansion of relative and abbreviated path specifiers.</p>

<emu-note>
<p>The above text implies that hosts *must* support JSON modules imported with `type: "json"` (if it completes normally), but it doesn't prohibit hosts from supporting JSON modules imported with no type specified.</p>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<p>The above text implies that hosts *must* support JSON modules imported with `type: "json"` (if it completes normally), but it doesn't prohibit hosts from supporting JSON modules imported with no type specified.</p>
<p>The above text requires that hosts support JSON modules when imported with `type: "json"` (and HostLoadImportedModule completes normally), but it does not prohibit hosts from supporting JSON modules when imported without `type: "json"`.</p>

Copy link
Member

@michaelficarra michaelficarra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM otherwise.


<p>A <dfn variants="Synthetic Module Records">Synthetic Module Record</dfn> is used to represent information about a module that is defined by specifications. Its exported names are statically defined at creation as an argument to CreateSyntheticModule, while their corresponding values can change over time using SetSyntheticModuleExport. It has no imports or dependencies.</p>

<emu-note>A Synthetic Module Record could be used for defining a variety of module types: for example, built-in modules, or JSON modules, or CSS modules.</emu-note>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<emu-note>A Synthetic Module Record could be used for defining a variety of module types: for example, built-in modules, or JSON modules, or CSS modules.</emu-note>
<emu-note>A Synthetic Module Record could be used for defining a variety of module types: for example, JSON modules or CSS modules.</emu-note>

I would limit the examples to ones that exist today.

<tr>
<td>[[EvaluationSteps]]</td>
<td>an Abstract Closure</td>
<td>The initialization logic to perform upon evaluation of the module, taking the Synthetic Module Record as its sole argument. These will usually set up the exported values, by using SetSyntheticModuleExport. It must not modify [[ExportNames]]. It may return an abrupt completion.</td>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<td>The initialization logic to perform upon evaluation of the module, taking the Synthetic Module Record as its sole argument. These will usually set up the exported values, by using SetSyntheticModuleExport. It must not modify [[ExportNames]]. It may return an abrupt completion.</td>
<td>The initialization logic to perform upon evaluation of the module, taking the Synthetic Module Record as its sole argument. It must not modify [[ExportNames]]. It may return an abrupt completion.</td>

That sentence seems superfluous to me.


<emu-clause id="sec-createsyntheticmodule" type="abstract operation">
<h1>
CreateSyntheticModule (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with inlining it.

</h1>
<dl class="header">
<dt>description</dt>
<dd>It can be used to set or change the exported value for a pre-established export of a Synthetic Module Record.</dd>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<dd>It can be used to set or change the exported value for a pre-established export of a Synthetic Module Record.</dd>
<dd>It can be used to set or change the exported value for an existing export of a Synthetic Module Record.</dd>

@@ -28495,12 +28698,19 @@ <h1>
</ul>
<p>and it performs FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_) where _result_ is a normal completion, then it must perform FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_) with the same _result_ each time.</p>
</li>
<li>
<p>If _moduleRequest_.[[Attributes]] has an entry _entry_ such that _entry_.[[Key]] is *"type"* and _entry_.[[Value]] is *"json"*, the host environment must perform FinishLoadingImportedModule(_referrer_, _moduleRequest_, _payload_, _result_), where _result_ is either the Completion Record returned by an invokation of ParseJSONModule or a throw completion.</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find writing this as a normative requirement on a host hook roundabout. I see two callsites to HostLoadImportedModule, one in dynamic import and one in static import. WDYT about refactoring those callsites to directly handle JSON modules?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolo-ribaudo is this easy to do without significant refactoring? If not, it's fine. Don't have the full machinery in my head.

1. Set the LexicalEnvironment of _moduleContext_ to _module_.[[Environment]].
1. Suspend the currently running execution context.
1. Push _moduleContext_ on to the execution context stack; _moduleContext_ is now the running execution context.
1. Let _steps_ be _module_.[[EvaluationSteps]].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to put the result of [[EvaluationSteps]] into a promise, as below, then it needs to be constrained to actually return an ES value. Right now there is no such constraint, and the only actual use in the spec is an Abstract Closure which doesn't return anything.

My inclination is to say that in the case of a normal completion the value is not used, and instead we put undefined in the Promise.

<tr>
<td>[[EvaluationSteps]]</td>
<td>an Abstract Closure</td>
<td>The initialization logic to perform upon evaluation of the module, taking the Synthetic Module Record as its sole argument. These will usually set up the exported values, by using SetSyntheticModuleExport. It must not modify [[ExportNames]]. It may return an abrupt completion.</td>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the use case for returning an abrupt completion?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has stage 4 This PR represents a proposal that has achieved stage 4, and is ready to merge. has test262 tests normative change Affects behavior required to correctly evaluate some ECMAScript source text proposal This is related to a specific proposal, and will be closed/merged when the proposal reaches stage 4.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants