Skip to content

Commit

Permalink
Normative: Prohibit module attributes as cache keys
Browse files Browse the repository at this point in the history
This patch changes the invariants on hosts, requiring that module
attributes do not affect the interpretation of the module. Instead,
they may only be used for checks. This constraint may be relaxed
in the future, or willfully violated by hosts, but there would be
risk in doing so; an extensive note is added explaining this risk.

Addresses #64
  • Loading branch information
littledan committed Jun 4, 2020
1 parent 9811975 commit ce1a4bb
Showing 1 changed file with 13 additions and 4 deletions.
17 changes: 13 additions & 4 deletions spec.html
Original file line number Diff line number Diff line change
Expand Up @@ -113,22 +113,31 @@ <h1>Runtime Semantics: HostResolveImportedModule ( _referencingScriptOrModule_,
If a Module Record corresponding to the pair _referencingScriptOrModule_, <del>_specifier_</del>, <ins>_moduleRequest_</ins> does not exist or cannot be created, an exception must be thrown.
</li>
<li>
Each time this operation is called with a specific _referencingScriptOrModule_, <del>_specifier_,</del> <ins>_moduleRequest_</ins> pair as arguments it must return the same Module Record instance if it completes normally.
Each time this operation is called with a specific _referencingScriptOrModule_, <del>_specifier_,</del> <ins>_moduleRequest_.[[Specifier]]</ins> pair as arguments it must return the same Module Record instance if it completes normally.
</li>
<li>
<ins>
If _attributes_ has an entry _entry_ such that _entry_.[[Key]] is *"type"*, let _type_ be _entry_.[[Value]]. The following requirements apply:
<ul>
<li>If _type_ is *"json"*, then this algorithm must either invoke ParseJSONModule and return the resulting Module Record, or throw an exception.</li>
<li>Each time this operation is called with a specific _referencingScriptOrModule_, _moduleRequest_ pair as arguments, <em>if _moduleRequest_.[[Attributes]] differs only based on _entry_,</em> it must return the same Module Record instance if it completes normally.</li>
</ul>
</ins>
</li>
</ul>
<p>Multiple different _referencingScriptOrModule_, _specifier_ pairs may map to the same Module Record instance. The actual mapping semantic is implementation-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 alphabetic case folding and expansion of relative and abbreviated path specifiers.</p>
<p>Multiple different _referencingScriptOrModule_, <del>_specifier_</del> <ins>_moduleRequest_.[[Specifier]]</ins> pairs may map to the same Module Record instance. The actual mapping semantic is implementation-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 alphabetic case folding and expansion of relative and abbreviated path specifiers.</p>

<emu-note type=editor>
<p>The above text implies that, if a module is imported multiple times with different _moduleRequest_.[[Attributes]] values, then there can be just one possible "successful" value (possibly as a result of multiple different attributes), but that it can also fail with an exception thrown; this exception from one import does not rule out success with a different attribute list.</p>
<p>The restriction of of attributes to not affect the contents of the module or be part of the cache key is sometimes referred to as permitting only "check attributes" and not "evaluator attributes", where the latter would change the contents of the module. Future versions of this specification may relax this restriction, and it's understood that some hosts may be tempted to willfully violate this restriction, but the module attributes champion group advises caution with such a move. There are three possible ways to handle multiple imports of the same module with different attributes, if the attributes cause a change in the interpretation of the module:</p>
<ul>
<li><strong>Race</strong> and use the attribute that was requested by the first import. This seems broken--the second usage is ignored.</li>
<li><strong>Reject</strong> the module graph and don't load if attributes differ. This seems bad for composition--using two unrelated packages together could break, if they load the same module with disagreeing attributes.</li>
<li><strong>Clone</strong> and make two copies of the module, for the different ways it's transformed. In this case, the attributes would have to be part of the cache key. These semantics would run counter to the intuition that there is just one copy of the module.</li>
</ul>
<p>It's possible that one of these three options may make sense for a module load, on a case-by-case basis by attribute, but it's worth careful thought before making this choice.</p>
</emu-note>

<emu-note type=editor>
<p>The above text implies that, if a module is imported multiple times with different _type_ values, then there can be just one possible "successful" value (possibly as a result of multiple different types), but that it can also fail with an exception thrown; this exception from one import does not rule out success with a different type.</p>
<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. Some environments (for example, web browsers) are expected to require `with type: "json"`, and environments which want to restrict themselves to a compatible subset would do so as well.</p>
</emu-note>
</emu-clause>
Expand Down

0 comments on commit ce1a4bb

Please sign in to comment.