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

Replace each abstract op's preamble with a structured 'header'. #545

Merged
merged 1 commit into from
Jul 15, 2021

Conversation

jmdyck
Copy link
Collaborator

@jmdyck jmdyck commented Apr 16, 2016

Following up on issue 253, specifically #253 (comment)

For each abstract operation (241 in all), I have taken the information in the prose preamble (or failing that, in the section's h1), and recast it into a structure of the following form:

    <emu-operation-header>
      name: ExampleOperation
      parameters:
        * _foo_ : an Object
        * _bar_ : (optional) an integer that indicates something or other
      also has access to:
        * _qux_ : ...
      returns:
        * normal : an Object
        * abrupt : throw *TypeError*
      description: does something exemplary to the given object.
    </emu-operation-header>

This structure is just a strawman. If you like the idea but not this particular structure, I should be able to regenerate the info in a different structure. (So far, the conversion is all done by code.)

Here are some things you might want to change (and that I should be able to accomplish):

  • You might want to call it something other than <emu-operation-header>.
  • For parameters, you might want to restrict the after-colon info to just type and optionality;
    any info about how the parameter is interpreted or used would go into the description.
    (Mostly, that's what I've done, but there are exceptions.)
  • For returns, rather than the normal/abrupt dichotomy,
    you might want normal/continue/break/return/throw.
  • For the description, you might rename it to 'summary' or 'synopsis',
    and you might want it to appear right after the 'name' line.
    (You might want to split it into a one-liner that appears after the name,
    and (if necessary) a more detailed description that appears later,
    but it's unlikely I'd accomplish that in code.)

(You also might want this notation applied to other kinds of operations, such as concrete methods, internal methods, and syntax-discriminated operations.)

Note that, as much as possible, I've used wording from the existing preambles for the after-colon content, so there are inconsistencies. (E.g., for a parameter, it might say: Object, an Object, object, an object, or the object.) Eventually, you'd want to eliminate those inconsistencies, but I decided not to presume too much just yet.

Also, you will see lots of "TBD" ("to be determined"), because preambles often leave out details. In a later commit, I could try to fix TBDs based on info in algorithm steps.

@bterlson
Copy link
Member

In general I support this direction but I have some concerns. The huge benefit I see is that the more machine readability we have the better tooling we can have. It also removes some difficulty in conforming to editorial conventions if we can generate more boilerplate for each algorithm. Is there more you're after?

We have a ton already (yaml, emd, gmd, json in addition to html). I think aligning with YAML is probably the best bet.

Also, if we have all the info to generate the emu-clause aoid, header/signature, I would prefer not to have to enter it twice into the document. Perhaps another type of clause is called for, say emu-alg-clause, that defines a clause with an algorithm? This will not work for all cases so we'd as a fallback support emu-clause with aoid+metadata block+manual header+manual intro prose for those cases?

I have a vague worry that the encoding scheme above won't be expressive enough. While it works for what we have now, what if we needed to specify a signature like Foo ( a, [ b, c ] ) eg. where b and c are optional but must be provided together? That might push us to some sort of overload syntax.

returns should be completions. Prefer to name after the completion types, so normal and throw, typically.

I think parameters and completion values should be ECMAScript language or specification value types only for ease of processing (eg. Object. Any additional constraints/requirements could be put into the description.

I will think on this more, let me know your thoughts on above.

@jmdyck
Copy link
Collaborator Author

jmdyck commented Apr 18, 2016

Is there more you're after?

I'm also after the ability to statically check every operation invocation, not just for the throw/nothrow distinction of Issue #253, but also for the number and types of arguments. Currently, without declared parameter+return types, that's fairly tough.

I think aligning with YAML is probably the best bet.

Yeah, I looked at YAML, but it raised questions I didn't want to get into unless it was called for. For concreteness, how would you like the example parameters section to appear?

Perhaps another type of clause is called for, say emu-alg-clause, that defines a clause with an algorithm?

So something like:

    <emu-alg-clause id="sec-exampleoperation">    // no aoid="...", no <h1>
      <emu-operation-header>
        name: ExampleOperation
        ...
      </emu-operation-header>
      <emu-alg>
        ...
      </emu-alg>
    </emu-alg-clause>

But note that not every <emu-operation-header> is followed by an <emu-alg>. (E.g.: for ToPrimitive, it's followed by an <emu-table>, and for HostFoo, it's followed by <p>. Also, if the notation is extended to syntax-discriminated operations, then there are associated <emu-alg>s, but they're scattered throughout the spec.) So you might not want "alg" in the element name.

what if we needed to specify a signature like Foo ( a, [ b, c ] ) eg. where b and c are optional but must be provided together?

Well, you could just define Foo(a) and Foo(a,b,c) separately. And you could rename one of them, so that they get distinct aoids.

Or you could acknowledge that there will always be limits to the invocation constraints that can be expressed in the parameters, and just decide that coordinating the optionality of two parameters is beyond that limit. (I.e., just say it in the description and enforce it in the alg.)

(Or don't invent such an operation.)

returns should be completions.

That assumes that every operation returns a Completion Record, which is still an open issue (Issue #496). And even if it's decided that every op does return a CR, it still wouldn't be wrong to say returns, because that is what an operation does.

Prefer to name after the completion types, so normal and throw, typically.

Okay.

I think parameters and completion values should be ECMAScript language or specification value types only for ease of processing (eg. Object. Any additional constraints/requirements could be put into the description.

Yup, makes sense. But note that that's not currently possible in all cases. Consider:

  • disjunction of two types (e.g., a String or Symbol, an object or null)
  • enumeration of spec values (e.g., either ~assignment~, ~varBinding~ or ~lexicalBinding~)

For the first, you might want to allow String | Symbol, as in various "Value Type" columns. For the second, you might want to create some more spec-type names.

Also, if the type is List, it would probably be useful to say what the type of its elements is.

And if the type is Parse Tree Node (or whatever we decide to call that), it would probably be useful to say (or have the option of saying) what the root symbol is.

Those are just a few examples, I'll have more as I work on it.

@bterlson
Copy link
Member

Yeah, I looked at YAML, but it raised questions I didn't want to get into unless it was called for. For concreteness, how would you like the example parameters section to appear?

Something like:

    <emu-operation-header>
      name: ExampleOperation
      parameters:
        - foo: Object
        - bar: (optional) an integer that indicates something or other

Though I'm not sure if this technically requires an !!omap? Not a yaml expert but above seems to work for js-yaml.

But note that not every <emu-operation-header> is followed by an <emu-alg>

Even if we can't avoid duplicating in some edge cases (eg. cases where there isn't an algorithm but a table, or we can't use the standard header and prose description for some reason) that seems ok. Syntax discriminated abstract ops are very common but I don't see an easy way to author those as part of this framework.

(Or don't invent such an operation.)

Probably the easiest way forward :-P I was just theorizing. We're kind of inventing a light-weight markup-and-YAML-based type annotation system so that lets me compare this system with others, eg. TS, which supports overloads for this scenario.

That assumes that every operation returns a Completion Record, which is still an open issue (Issue #496). And even if it's decided that every op does return a CR, it still wouldn't be wrong to say returns , because that is what an operation does.

I'm not saying returns is wrong. I prefer completions weakly because the things that follow below it are completions most of the time. But I don't care much.

For the first, you might want to allow String | Symbol , as in various "Value Type" columns. For the second, you might want to create some more spec-type names.

I like String | Symbol (aka TS Union types). I also like String[] for an array of strings for same reason.

@jmdyck
Copy link
Collaborator Author

jmdyck commented Apr 19, 2016

For concreteness, how would you like the example parameters section to appear?

Something like:

    <emu-operation-header>
      name: ExampleOperation
      parameters:
       - foo: Object
       - bar: (optional) an integer that indicates something or other

Thanks. Is the use of foo rather than _foo_ deliberate?

Though I'm not sure if this technically requires an !!omap?

I don't think so.

Syntax discriminated abstract ops are very common but I don't see an easy way to author those as part of this framework.

I should be clearer: I was thinking it would be useful to have, for each syntax-discriminated op, a single declaration (which could, for instance, auto-link to all the sections that contribute to the definition of that op). The single decl could use <emu-operation-header>, but the contributing sections would not (though they could link to the result of rendering the single decl).

I also like String[] for an array of strings for same reason.

I don't think there are currently any operations that take or return an array of strings. Do you mean a list of strings? If so, I'd be leery of using square brackets, since they suggest arrays. Instead, at least in the short term, I'd be inclined to use List of String, as appears in Tables 18 and 29.

@jmdyck
Copy link
Collaborator Author

jmdyck commented Apr 27, 2016

In the latest commit, I've used unofficial type names (or type unions thereof) for parameters that don't have officially-named types (other than TBD). (Resolving 'TBD's will doubtless introduce more.) Each unofficial name ends with an underscore, for ease of identification.

In the following list, "X: Y" means that unofficial type X is the set of values each of which is Y

  • Tangible_: an ECMAScript language value. (Normally, I might have used 'Concrete' vs 'Abstract' to name the (super)types of language vs specification values. However, the spec already uses those terms with other meanings, so I went for Tangible vs Intangible.)
  • function_object_: an object with a [[Call]] internal method
  • constructor_object_: an object with a [[Construct]] internal method
  • ArrayBuffer_object_: an object with an [[ArrayBufferData]] internal slot
  • TypedArray_object_: a TypedArray instance
  • Array_object_: an Array exotic object
  • IteratorResult_object_: an object that implements the IteratorResult interface
  • Integer_: an integer
  • Infinity_: infinity
  • SlotName_: the name of an internal slot
  • LangTypeName_: the name of an ECMAScript language type
  • code_unit_: a code unit
  • character_: a character (in the particular sense given in 21.2.2 "Pattern Semantics")
  • ParseTreeNode_: what the spec refers to as a parse node, a parsed grammar phrase, the result of parsing some source text, or (incorrectly) a production.
  • FunctionKind1_: one of (Normal, Method, Arrow)
  • FunctionKind2_: either "normal" or "generator"
  • IterationKind_: either enumerate or iterate
  • LhsKind_: either assignment, varBinding or lexicalBinding

@jmdyck jmdyck force-pushed the operation_headers branch from 7374c33 to b1a0637 Compare May 11, 2016 19:13
@jmdyck jmdyck force-pushed the operation_headers branch 3 times, most recently from ac87a13 to 4306c7b Compare June 9, 2016 20:35
@jmdyck jmdyck force-pushed the operation_headers branch from 4306c7b to 354b45b Compare July 6, 2016 20:46
@jmdyck jmdyck force-pushed the operation_headers branch from 354b45b to b185c0d Compare July 26, 2016 22:05
@jmdyck jmdyck force-pushed the operation_headers branch from b185c0d to 7b59ca7 Compare August 22, 2016 19:30
@jmdyck jmdyck force-pushed the operation_headers branch 2 times, most recently from 8eef0c0 to 97b1f80 Compare November 15, 2016 19:09
@jmdyck jmdyck force-pushed the operation_headers branch from 2f17b88 to c7a0ac1 Compare February 6, 2017 05:07
@jmdyck jmdyck force-pushed the operation_headers branch 3 times, most recently from 78b66fb to ad3ec37 Compare February 18, 2017 17:47
@jmdyck jmdyck force-pushed the operation_headers branch from 7c14226 to c8ae63d Compare June 24, 2021 18:14
@ljharb ljharb force-pushed the master branch 3 times, most recently from 3d0c24c to 7a79833 Compare June 29, 2021 02:21
jmdyck added a commit to jmdyck/ecma262 that referenced this pull request Jul 1, 2021
for:
 - abstract operations
 - numeric methods
 - 'concrete' methods
 - internal methods
@jmdyck jmdyck force-pushed the operation_headers branch from c8ae63d to b1ac781 Compare July 1, 2021 01:23
jmdyck added a commit to jmdyck/ecma262 that referenced this pull request Jul 11, 2021
for:
 - abstract operations
 - numeric methods
 - 'concrete' methods
 - internal methods
@jmdyck jmdyck force-pushed the operation_headers branch from b1ac781 to db84630 Compare July 11, 2021 21:49
jmdyck added a commit to jmdyck/ecma262 that referenced this pull request Jul 14, 2021
for:
 - abstract operations
 - numeric methods
 - 'concrete' methods
 - internal methods
@jmdyck jmdyck force-pushed the operation_headers branch from db84630 to da85f72 Compare July 14, 2021 22:37
@bakkot
Copy link
Contributor

bakkot commented Jul 14, 2021

Here's an almost-complete diff of the generated HTML vs that of HEAD. (I've suppressed differences from generated ID numbers and from the order of the aoid attribute among all the attributes of a tags.)

As you can see there's just a few changes:

  • every numeric method gets an AOID
    • which means that places that referred to a numeric method explicitly now link appropriately
  • the InitializeEnvironment and a ExecuteModule concrete methods of Source Text Module Records no longer have AOIDs, in keeping with every other concrete method in the spec
    • which means that places that referred to one of them no longer link
  • StringToBigInt gets a The abstract operation StringToBigInt takes argument _argument_ introduction
  • a few places have ", and returns" changed to ". It returns"
  • an "arguments" -> "argument" typo is fixed

I think this is ready to be merged, pending stamps from other editors.

@@ -1563,3 +1563,3 @@
 
-        <emu-clause id="sec-numeric-types-number-unaryMinus">
+        <emu-clause id="sec-numeric-types-number-unaryMinus" aoid="Number::unaryMinus">
           <h1><span class="secnum">6.1.6.1.1</span> Number::unaryMinus ( <var>x</var> )</h1>
@@ -1569,3 +1569,3 @@
 
-        <emu-clause id="sec-numeric-types-number-bitwiseNOT">
+        <emu-clause id="sec-numeric-types-number-bitwiseNOT" aoid="Number::bitwiseNOT">
           <h1><span class="secnum">6.1.6.1.2</span> Number::bitwiseNOT ( <var>x</var> )</h1>
@@ -1575,3 +1575,3 @@
 
-        <emu-clause id="sec-numeric-types-number-exponentiate" oldids="sec-applying-the-exp-operator"><span id="sec-applying-the-exp-operator"></span>
+        <emu-clause id="sec-numeric-types-number-exponentiate" oldids="sec-applying-the-exp-operator" aoid="Number::exponentiate"><span id="sec-applying-the-exp-operator"></span>
           <h1><span class="secnum">6.1.6.1.3</span> Number::exponentiate ( <var>base</var>, <var>exponent</var> )</h1>
@@ -1584,3 +1584,3 @@
 
-        <emu-clause id="sec-numeric-types-number-multiply" oldids="sec-applying-the-mul-operator"><span id="sec-applying-the-mul-operator"></span>
+        <emu-clause id="sec-numeric-types-number-multiply" oldids="sec-applying-the-mul-operator" aoid="Number::multiply"><span id="sec-applying-the-mul-operator"></span>
           <h1><span class="secnum">6.1.6.1.4</span> Number::multiply ( <var>x</var>, <var>y</var> )</h1>
@@ -1593,3 +1593,3 @@
 
-        <emu-clause id="sec-numeric-types-number-divide" oldids="sec-applying-the-div-operator"><span id="sec-applying-the-div-operator"></span>
+        <emu-clause id="sec-numeric-types-number-divide" oldids="sec-applying-the-div-operator" aoid="Number::divide"><span id="sec-applying-the-div-operator"></span>
           <h1><span class="secnum">6.1.6.1.5</span> Number::divide ( <var>x</var>, <var>y</var> )</h1>
@@ -1599,3 +1599,3 @@
 
-        <emu-clause id="sec-numeric-types-number-remainder" oldids="sec-applying-the-mod-operator"><span id="sec-applying-the-mod-operator"></span>
+        <emu-clause id="sec-numeric-types-number-remainder" oldids="sec-applying-the-mod-operator" aoid="Number::remainder"><span id="sec-applying-the-mod-operator"></span>
           <h1><span class="secnum">6.1.6.1.6</span> Number::remainder ( <var>n</var>, <var>d</var> )</h1>
@@ -1609,3 +1609,3 @@
 
-        <emu-clause id="sec-numeric-types-number-add" oldids="sec-applying-the-additive-operators-to-numbers"><span id="sec-applying-the-additive-operators-to-numbers"></span>
+        <emu-clause id="sec-numeric-types-number-add" oldids="sec-applying-the-additive-operators-to-numbers" aoid="Number::add"><span id="sec-applying-the-additive-operators-to-numbers"></span>
           <h1><span class="secnum">6.1.6.1.7</span> Number::add ( <var>x</var>, <var>y</var> )</h1>
@@ -1618,6 +1618,6 @@
 
-        <emu-clause id="sec-numeric-types-number-subtract">
+        <emu-clause id="sec-numeric-types-number-subtract" aoid="Number::subtract">
           <h1><span class="secnum">6.1.6.1.8</span> Number::subtract ( <var>x</var>, <var>y</var> )</h1>
           <p>The abstract operation Number::subtract takes arguments <var>x</var> (a Number) and <var>y</var> (a Number). It performs subtraction, producing the difference of its operands; <var>x</var> is the minuend and <var>y</var> is the subtrahend. It performs the following steps when called:</p>
-          <emu-alg><ol><li>Return Number::add(<var>x</var>, Number::unaryMinus(<var>y</var>)).</li></ol></emu-alg>
+          <emu-alg><ol><li>Return <emu-xref aoid="Number::add" id=""><a href="#sec-numeric-types-number-add">Number::add</a></emu-xref>(<var>x</var>, <emu-xref aoid="Number::unaryMinus" id=""><a href="#sec-numeric-types-number-unaryMinus">Number::unaryMinus</a></emu-xref>(<var>y</var>)).</li></ol></emu-alg>
           <emu-note><span class="note">Note</span><div class="note-contents">
@@ -1627,3 +1627,3 @@
 
-        <emu-clause id="sec-numeric-types-number-leftShift">
+        <emu-clause id="sec-numeric-types-number-leftShift" aoid="Number::leftShift">
           <h1><span class="secnum">6.1.6.1.9</span> Number::leftShift ( <var>x</var>, <var>y</var> )</h1>
@@ -1633,3 +1633,3 @@
 
-        <emu-clause id="sec-numeric-types-number-signedRightShift">
+        <emu-clause id="sec-numeric-types-number-signedRightShift" aoid="Number::signedRightShift">
           <h1><span class="secnum">6.1.6.1.10</span> Number::signedRightShift ( <var>x</var>, <var>y</var> )</h1>
@@ -1639,3 +1639,3 @@
 
-        <emu-clause id="sec-numeric-types-number-unsignedRightShift">
+        <emu-clause id="sec-numeric-types-number-unsignedRightShift" aoid="Number::unsignedRightShift">
           <h1><span class="secnum">6.1.6.1.11</span> Number::unsignedRightShift ( <var>x</var>, <var>y</var> )</h1>
@@ -1645,3 +1645,3 @@
 
-        <emu-clause id="sec-numeric-types-number-lessThan">
+        <emu-clause id="sec-numeric-types-number-lessThan" aoid="Number::lessThan">
           <h1><span class="secnum">6.1.6.1.12</span> Number::lessThan ( <var>x</var>, <var>y</var> )</h1>
@@ -1651,3 +1651,3 @@
 
-        <emu-clause id="sec-numeric-types-number-equal">
+        <emu-clause id="sec-numeric-types-number-equal" aoid="Number::equal">
           <h1><span class="secnum">6.1.6.1.13</span> Number::equal ( <var>x</var>, <var>y</var> )</h1>
@@ -1657,3 +1657,3 @@
 
-        <emu-clause id="sec-numeric-types-number-sameValue">
+        <emu-clause id="sec-numeric-types-number-sameValue" aoid="Number::sameValue">
           <h1><span class="secnum">6.1.6.1.14</span> Number::sameValue ( <var>x</var>, <var>y</var> )</h1>
@@ -1663,3 +1663,3 @@
 
-        <emu-clause id="sec-numeric-types-number-sameValueZero">
+        <emu-clause id="sec-numeric-types-number-sameValueZero" aoid="Number::sameValueZero">
           <h1><span class="secnum">6.1.6.1.15</span> Number::sameValueZero ( <var>x</var>, <var>y</var> )</h1>
@@ -1675,3 +1675,3 @@
 
-        <emu-clause id="sec-numeric-types-number-bitwiseAND">
+        <emu-clause id="sec-numeric-types-number-bitwiseAND" aoid="Number::bitwiseAND">
           <h1><span class="secnum">6.1.6.1.17</span> Number::bitwiseAND ( <var>x</var>, <var>y</var> )</h1>
@@ -1681,3 +1681,3 @@
 
-        <emu-clause id="sec-numeric-types-number-bitwiseXOR">
+        <emu-clause id="sec-numeric-types-number-bitwiseXOR" aoid="Number::bitwiseXOR">
           <h1><span class="secnum">6.1.6.1.18</span> Number::bitwiseXOR ( <var>x</var>, <var>y</var> )</h1>
@@ -1687,3 +1687,3 @@
 
-        <emu-clause id="sec-numeric-types-number-bitwiseOR">
+        <emu-clause id="sec-numeric-types-number-bitwiseOR" aoid="Number::bitwiseOR">
           <h1><span class="secnum">6.1.6.1.19</span> Number::bitwiseOR ( <var>x</var>, <var>y</var> )</h1>
@@ -1731,3 +1731,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-unaryMinus">
+        <emu-clause id="sec-numeric-types-bigint-unaryMinus" aoid="BigInt::unaryMinus">
           <h1><span class="secnum">6.1.6.2.1</span> BigInt::unaryMinus ( <var>x</var> )</h1>
@@ -1737,3 +1737,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-bitwiseNOT">
+        <emu-clause id="sec-numeric-types-bigint-bitwiseNOT" aoid="BigInt::bitwiseNOT">
           <h1><span class="secnum">6.1.6.2.2</span> BigInt::bitwiseNOT ( <var>x</var> )</h1>
@@ -1742,3 +1742,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-exponentiate">
+        <emu-clause id="sec-numeric-types-bigint-exponentiate" aoid="BigInt::exponentiate">
           <h1><span class="secnum">6.1.6.2.3</span> BigInt::exponentiate ( <var>base</var>, <var>exponent</var> )</h1>
@@ -1748,3 +1748,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-multiply">
+        <emu-clause id="sec-numeric-types-bigint-multiply" aoid="BigInt::multiply">
           <h1><span class="secnum">6.1.6.2.4</span> BigInt::multiply ( <var>x</var>, <var>y</var> )</h1>
@@ -1754,3 +1754,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-divide">
+        <emu-clause id="sec-numeric-types-bigint-divide" aoid="BigInt::divide">
           <h1><span class="secnum">6.1.6.2.5</span> BigInt::divide ( <var>x</var>, <var>y</var> )</h1>
@@ -1760,3 +1760,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-remainder">
+        <emu-clause id="sec-numeric-types-bigint-remainder" aoid="BigInt::remainder">
           <h1><span class="secnum">6.1.6.2.6</span> BigInt::remainder ( <var>n</var>, <var>d</var> )</h1>
@@ -1767,3 +1767,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-add">
+        <emu-clause id="sec-numeric-types-bigint-add" aoid="BigInt::add">
           <h1><span class="secnum">6.1.6.2.7</span> BigInt::add ( <var>x</var>, <var>y</var> )</h1>
@@ -1772,3 +1772,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-subtract">
+        <emu-clause id="sec-numeric-types-bigint-subtract" aoid="BigInt::subtract">
           <h1><span class="secnum">6.1.6.2.8</span> BigInt::subtract ( <var>x</var>, <var>y</var> )</h1>
@@ -1777,3 +1777,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-leftShift">
+        <emu-clause id="sec-numeric-types-bigint-leftShift" aoid="BigInt::leftShift">
           <h1><span class="secnum">6.1.6.2.9</span> BigInt::leftShift ( <var>x</var>, <var>y</var> )</h1>
@@ -1784,9 +1784,9 @@
 
-        <emu-clause id="sec-numeric-types-bigint-signedRightShift">
+        <emu-clause id="sec-numeric-types-bigint-signedRightShift" aoid="BigInt::signedRightShift">
           <h1><span class="secnum">6.1.6.2.10</span> BigInt::signedRightShift ( <var>x</var>, <var>y</var> )</h1>
           <p>The abstract operation BigInt::signedRightShift takes arguments <var>x</var> (a BigInt) and <var>y</var> (a BigInt). It performs the following steps when called:</p>
-          <emu-alg><ol><li>Return BigInt::leftShift(<var>x</var>, -<var>y</var>).</li></ol></emu-alg>
+          <emu-alg><ol><li>Return <emu-xref aoid="BigInt::leftShift" id=""><a href="#sec-numeric-types-bigint-leftShift">BigInt::leftShift</a></emu-xref>(<var>x</var>, -<var>y</var>).</li></ol></emu-alg>
         </emu-clause>
 
-        <emu-clause id="sec-numeric-types-bigint-unsignedRightShift">
+        <emu-clause id="sec-numeric-types-bigint-unsignedRightShift" aoid="BigInt::unsignedRightShift">
           <h1><span class="secnum">6.1.6.2.11</span> BigInt::unsignedRightShift ( <var>x</var>, <var>y</var> )</h1>
@@ -1796,3 +1796,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-lessThan">
+        <emu-clause id="sec-numeric-types-bigint-lessThan" aoid="BigInt::lessThan">
           <h1><span class="secnum">6.1.6.2.12</span> BigInt::lessThan ( <var>x</var>, <var>y</var> )</h1>
@@ -1801,3 +1801,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-equal">
+        <emu-clause id="sec-numeric-types-bigint-equal" aoid="BigInt::equal">
           <h1><span class="secnum">6.1.6.2.13</span> BigInt::equal ( <var>x</var>, <var>y</var> )</h1>
@@ -1806,12 +1806,12 @@
 
-        <emu-clause id="sec-numeric-types-bigint-sameValue">
+        <emu-clause id="sec-numeric-types-bigint-sameValue" aoid="BigInt::sameValue">
           <h1><span class="secnum">6.1.6.2.14</span> BigInt::sameValue ( <var>x</var>, <var>y</var> )</h1>
           <p>The abstract operation BigInt::sameValue takes arguments <var>x</var> (a BigInt) and <var>y</var> (a BigInt). It performs the following steps when called:</p>
-          <emu-alg><ol><li>Return BigInt::equal(<var>x</var>, <var>y</var>).</li></ol></emu-alg>
+          <emu-alg><ol><li>Return <emu-xref aoid="BigInt::equal" id=""><a href="#sec-numeric-types-bigint-equal">BigInt::equal</a></emu-xref>(<var>x</var>, <var>y</var>).</li></ol></emu-alg>
         </emu-clause>
 
-        <emu-clause id="sec-numeric-types-bigint-sameValueZero">
+        <emu-clause id="sec-numeric-types-bigint-sameValueZero" aoid="BigInt::sameValueZero">
           <h1><span class="secnum">6.1.6.2.15</span> BigInt::sameValueZero ( <var>x</var>, <var>y</var> )</h1>
           <p>The abstract operation BigInt::sameValueZero takes arguments <var>x</var> (a BigInt) and <var>y</var> (a BigInt). It performs the following steps when called:</p>
-          <emu-alg><ol><li>Return BigInt::equal(<var>x</var>, <var>y</var>).</li></ol></emu-alg>
+          <emu-alg><ol><li>Return <emu-xref aoid="BigInt::equal" id=""><a href="#sec-numeric-types-bigint-equal">BigInt::equal</a></emu-xref>(<var>x</var>, <var>y</var>).</li></ol></emu-alg>
         </emu-clause>
@@ -1842,3 +1842,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-bitwiseAND">
+        <emu-clause id="sec-numeric-types-bigint-bitwiseAND" aoid="BigInt::bitwiseAND">
           <h1><span class="secnum">6.1.6.2.20</span> BigInt::bitwiseAND ( <var>x</var>, <var>y</var> )</h1>
@@ -1848,3 +1848,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-bitwiseXOR">
+        <emu-clause id="sec-numeric-types-bigint-bitwiseXOR" aoid="BigInt::bitwiseXOR">
           <h1><span class="secnum">6.1.6.2.21</span> BigInt::bitwiseXOR ( <var>x</var>, <var>y</var> )</h1>
@@ -1854,3 +1854,3 @@
 
-        <emu-clause id="sec-numeric-types-bigint-bitwiseOR">
+        <emu-clause id="sec-numeric-types-bigint-bitwiseOR" aoid="BigInt::bitwiseOR">
           <h1><span class="secnum">6.1.6.2.22</span> BigInt::bitwiseOR ( <var>x</var>, <var>y</var> )</h1>
@@ -4002,3 +4002,3 @@
 
-        <emu-clause id="sec-runtime-semantics-stringnumericvalue" type="sdo" oldids="sec-runtime-semantics-mv-s" aoid="StringNumericValue"><span id="sec-runtime-semantics-mv-s"></span>
+        <emu-clause id="sec-runtime-semantics-stringnumericvalue" type="sdo" aoid="StringNumericValue" oldids="sec-runtime-semantics-mv-s"><span id="sec-runtime-semantics-mv-s"></span>
           <h1><span class="secnum">7.1.4.1.1</span> Runtime Semantics: StringNumericValue</h1>
@@ -4245,2 +4245,3 @@
       <h1><span class="secnum">7.1.14</span> StringToBigInt ( <var>argument</var> )</h1>
+      <p>The abstract operation StringToBigInt takes argument <var>argument</var>.</p>
       <p>Apply the algorithm in <emu-xref href="#sec-tonumber-applied-to-the-string-type" id=""><a href="#sec-tonumber-applied-to-the-string-type">7.1.4.1</a></emu-xref> with the following changes:</p>
@@ -4564,3 +4565,3 @@
       <h1><span class="secnum">7.2.5</span> IsExtensible ( <var>O</var> )</h1>
-      <p>The abstract operation IsExtensible takes argument <var>O</var> (an Object) and returns a completion record which, if its [[Type]] is <emu-const>normal</emu-const>, has a [[Value]] which is a Boolean. It is used to determine whether additional properties can be added to <var>O</var>. It performs the following steps when called:</p>
+      <p>The abstract operation IsExtensible takes argument <var>O</var> (an Object). It returns a completion record which, if its [[Type]] is <emu-const>normal</emu-const>, has a [[Value]] which is a Boolean. It is used to determine whether additional properties can be added to <var>O</var>. It performs the following steps when called:</p>
       <emu-alg><ol><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>O</var>) is Object.</li><li>Return ? <var>O</var>.[[IsExtensible]]().</li></ol></emu-alg>
@@ -4597,3 +4598,3 @@
       <h1><span class="secnum">7.2.10</span> SameValue ( <var>x</var>, <var>y</var> )</h1>
-      <p>The abstract operation SameValue takes arguments <var>x</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>) and <var>y</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>) and returns a completion record whose [[Type]] is <emu-const>normal</emu-const> and whose [[Value]] is a Boolean. It performs the following steps when called:</p>
+      <p>The abstract operation SameValue takes arguments <var>x</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>) and <var>y</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>). It returns a completion record whose [[Type]] is <emu-const>normal</emu-const> and whose [[Value]] is a Boolean. It performs the following steps when called:</p>
       <emu-alg><ol><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>) is different from <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>y</var>), return <emu-val>false</emu-val>.</li><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>) is Number or BigInt, then<ol><li>Return !&nbsp;<emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>)::sameValue(<var>x</var>, <var>y</var>).</li></ol></li><li>Return !&nbsp;<emu-xref aoid="SameValueNonNumeric" id=""><a href="#sec-samevaluenonnumeric">SameValueNonNumeric</a></emu-xref>(<var>x</var>, <var>y</var>).</li></ol></emu-alg>
@@ -4606,3 +4607,3 @@
       <h1><span class="secnum">7.2.11</span> SameValueZero ( <var>x</var>, <var>y</var> )</h1>
-      <p>The abstract operation SameValueZero takes arguments <var>x</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>) and <var>y</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>) and returns a completion record whose [[Type]] is <emu-const>normal</emu-const> and whose [[Value]] is a Boolean. It performs the following steps when called:</p>
+      <p>The abstract operation SameValueZero takes arguments <var>x</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>) and <var>y</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>). It returns a completion record whose [[Type]] is <emu-const>normal</emu-const> and whose [[Value]] is a Boolean. It performs the following steps when called:</p>
       <emu-alg><ol><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>) is different from <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>y</var>), return <emu-val>false</emu-val>.</li><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>) is Number or BigInt, then<ol><li>Return !&nbsp;<emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>)::sameValueZero(<var>x</var>, <var>y</var>).</li></ol></li><li>Return !&nbsp;<emu-xref aoid="SameValueNonNumeric" id=""><a href="#sec-samevaluenonnumeric">SameValueNonNumeric</a></emu-xref>(<var>x</var>, <var>y</var>).</li></ol></emu-alg>
@@ -4615,3 +4616,3 @@
       <h1><span class="secnum">7.2.12</span> SameValueNonNumeric ( <var>x</var>, <var>y</var> )</h1>
-      <p>The abstract operation SameValueNonNumeric takes arguments <var>x</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>) and <var>y</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>) and returns a completion record whose [[Type]] is <emu-const>normal</emu-const> and whose [[Value]] is a Boolean. It performs the following steps when called:</p>
+      <p>The abstract operation SameValueNonNumeric takes arguments <var>x</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>) and <var>y</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>). It returns a completion record whose [[Type]] is <emu-const>normal</emu-const> and whose [[Value]] is a Boolean. It performs the following steps when called:</p>
       <emu-alg><ol><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>) is not Number or BigInt.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>) is the same as <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>y</var>).</li><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>) is Undefined, return <emu-val>true</emu-val>.</li><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>) is Null, return <emu-val>true</emu-val>.</li><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>) is String, then<ol><li>If <var>x</var> and <var>y</var> are exactly the same sequence of code units (same length and same code units at corresponding indices), return <emu-val>true</emu-val>; otherwise, return <emu-val>false</emu-val>.</li></ol></li><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>) is Boolean, then<ol><li>If <var>x</var> and <var>y</var> are both <emu-val>true</emu-val> or both <emu-val>false</emu-val>, return <emu-val>true</emu-val>; otherwise, return <emu-val>false</emu-val>.</li></ol></li><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>x</var>) is Symbol, then<ol><li>If <var>x</var> and <var>y</var> are both the same Symbol value, return <emu-val>true</emu-val>; otherwise, return <emu-val>false</emu-val>.</li></ol></li><li>If <var>x</var> and <var>y</var> are the same Object value, return <emu-val>true</emu-val>. Otherwise, return <emu-val>false</emu-val>.</li></ol></emu-alg>
@@ -4622,3 +4623,3 @@
       <p>The abstract operation IsLessThan takes arguments <var>x</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>), <var>y</var> (an <emu-xref href="#sec-ecmascript-language-types" id=""><a href="#sec-ecmascript-language-types">ECMAScript language value</a></emu-xref>), and <var>LeftFirst</var> (a Boolean). It provides the semantics for the comparison <var>x</var> &lt; <var>y</var>, returning <emu-val>true</emu-val>, <emu-val>false</emu-val>, or <emu-val>undefined</emu-val> (which indicates that at least one operand is <emu-val>NaN</emu-val>). The <var>LeftFirst</var> flag is used to control the order in which operations with potentially visible side-effects are performed upon <var>x</var> and <var>y</var>. It is necessary because ECMAScript specifies left to right evaluation of expressions. If <var>LeftFirst</var> is <emu-val>true</emu-val>, the <var>x</var> parameter corresponds to an expression that occurs to the left of the <var>y</var> parameter's corresponding expression. If <var>LeftFirst</var> is <emu-val>false</emu-val>, the reverse is the case and operations must be performed upon <var>y</var> before <var>x</var>. It performs the following steps when called:</p>
-      <emu-alg><ol><li>If the <var>LeftFirst</var> flag is <emu-val>true</emu-val>, then<ol><li>Let <var>px</var> be ?&nbsp;<emu-xref aoid="ToPrimitive" id=""><a href="#sec-toprimitive">ToPrimitive</a></emu-xref>(<var>x</var>, <emu-const>number</emu-const>).</li><li>Let <var>py</var> be ?&nbsp;<emu-xref aoid="ToPrimitive" id=""><a href="#sec-toprimitive">ToPrimitive</a></emu-xref>(<var>y</var>, <emu-const>number</emu-const>).</li></ol></li><li>Else,<ol><li>NOTE: The order of evaluation needs to be reversed to preserve left to right evaluation.</li><li>Let <var>py</var> be ?&nbsp;<emu-xref aoid="ToPrimitive" id=""><a href="#sec-toprimitive">ToPrimitive</a></emu-xref>(<var>y</var>, <emu-const>number</emu-const>).</li><li>Let <var>px</var> be ?&nbsp;<emu-xref aoid="ToPrimitive" id=""><a href="#sec-toprimitive">ToPrimitive</a></emu-xref>(<var>x</var>, <emu-const>number</emu-const>).</li></ol></li><li id="step-arc-string-check">If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>px</var>) is String and <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>py</var>) is String, then<ol><li>If <emu-xref aoid="IsStringPrefix" id=""><a href="#sec-isstringprefix">IsStringPrefix</a></emu-xref>(<var>py</var>, <var>px</var>) is <emu-val>true</emu-val>, return <emu-val>false</emu-val>.</li><li>If <emu-xref aoid="IsStringPrefix" id=""><a href="#sec-isstringprefix">IsStringPrefix</a></emu-xref>(<var>px</var>, <var>py</var>) is <emu-val>true</emu-val>, return <emu-val>true</emu-val>.</li><li>Let <var>k</var> be the smallest non-negative <emu-xref href="#integer" id=""><a href="#integer">integer</a></emu-xref> such that the code unit at index <var>k</var> within <var>px</var> is different from the code unit at index <var>k</var> within <var>py</var>. (There must be such a <var>k</var>, for neither String is a prefix of the other.)</li><li>Let <var>m</var> be the <emu-xref href="#integer" id=""><a href="#integer">integer</a></emu-xref> that is the numeric value of the code unit at index <var>k</var> within <var>px</var>.</li><li>Let <var>n</var> be the <emu-xref href="#integer" id=""><a href="#integer">integer</a></emu-xref> that is the numeric value of the code unit at index <var>k</var> within <var>py</var>.</li><li>If <var>m</var> &lt; <var>n</var>, return <emu-val>true</emu-val>. Otherwise, return <emu-val>false</emu-val>.</li></ol></li><li>Else,<ol><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>px</var>) is BigInt and <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>py</var>) is String, then<ol><li>Let <var>ny</var> be !&nbsp;<emu-xref aoid="StringToBigInt" id=""><a href="#sec-stringtobigint">StringToBigInt</a></emu-xref>(<var>py</var>).</li><li>If <var>ny</var> is <emu-val>NaN</emu-val>, return <emu-val>undefined</emu-val>.</li><li>Return BigInt::lessThan(<var>px</var>, <var>ny</var>).</li></ol></li><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>px</var>) is String and <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>py</var>) is BigInt, then<ol><li>Let <var>nx</var> be !&nbsp;<emu-xref aoid="StringToBigInt" id=""><a href="#sec-stringtobigint">StringToBigInt</a></emu-xref>(<var>px</var>).</li><li>If <var>nx</var> is <emu-val>NaN</emu-val>, return <emu-val>undefined</emu-val>.</li><li>Return BigInt::lessThan(<var>nx</var>, <var>py</var>).</li></ol></li><li>NOTE: Because <var>px</var> and <var>py</var> are primitive values, evaluation order is not important.</li><li>Let <var>nx</var> be ?&nbsp;<emu-xref aoid="ToNumeric" id=""><a href="#sec-tonumeric">ToNumeric</a></emu-xref>(<var>px</var>).</li><li>Let <var>ny</var> be ?&nbsp;<emu-xref aoid="ToNumeric" id=""><a href="#sec-tonumeric">ToNumeric</a></emu-xref>(<var>py</var>).</li><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>nx</var>) is the same as <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>ny</var>), return <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>nx</var>)::lessThan(<var>nx</var>, <var>ny</var>).</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>nx</var>) is BigInt and <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>ny</var>) is Number, or <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>nx</var>) is Number and <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>ny</var>) is BigInt.</li><li>If <var>nx</var> or <var>ny</var> is <emu-val>NaN</emu-val>, return <emu-val>undefined</emu-val>.</li><li>If <var>nx</var> is <emu-val>-∞</emu-val><sub>𝔽</sub> or <var>ny</var> is <emu-val>+∞</emu-val><sub>𝔽</sub>, return <emu-val>true</emu-val>.</li><li>If <var>nx</var> is <emu-val>+∞</emu-val><sub>𝔽</sub> or <var>ny</var> is <emu-val>-∞</emu-val><sub>𝔽</sub>, return <emu-val>false</emu-val>.</li><li>If <emu-xref href="#ℝ" id=""><a href="#ℝ">ℝ</a></emu-xref>(<var>nx</var>) &lt; <emu-xref href="#ℝ" id=""><a href="#ℝ">ℝ</a></emu-xref>(<var>ny</var>), return <emu-val>true</emu-val>; otherwise return <emu-val>false</emu-val>.</li></ol></li></ol></emu-alg>
+      <emu-alg><ol><li>If the <var>LeftFirst</var> flag is <emu-val>true</emu-val>, then<ol><li>Let <var>px</var> be ?&nbsp;<emu-xref aoid="ToPrimitive" id=""><a href="#sec-toprimitive">ToPrimitive</a></emu-xref>(<var>x</var>, <emu-const>number</emu-const>).</li><li>Let <var>py</var> be ?&nbsp;<emu-xref aoid="ToPrimitive" id=""><a href="#sec-toprimitive">ToPrimitive</a></emu-xref>(<var>y</var>, <emu-const>number</emu-const>).</li></ol></li><li>Else,<ol><li>NOTE: The order of evaluation needs to be reversed to preserve left to right evaluation.</li><li>Let <var>py</var> be ?&nbsp;<emu-xref aoid="ToPrimitive" id=""><a href="#sec-toprimitive">ToPrimitive</a></emu-xref>(<var>y</var>, <emu-const>number</emu-const>).</li><li>Let <var>px</var> be ?&nbsp;<emu-xref aoid="ToPrimitive" id=""><a href="#sec-toprimitive">ToPrimitive</a></emu-xref>(<var>x</var>, <emu-const>number</emu-const>).</li></ol></li><li id="step-arc-string-check">If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>px</var>) is String and <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>py</var>) is String, then<ol><li>If <emu-xref aoid="IsStringPrefix" id=""><a href="#sec-isstringprefix">IsStringPrefix</a></emu-xref>(<var>py</var>, <var>px</var>) is <emu-val>true</emu-val>, return <emu-val>false</emu-val>.</li><li>If <emu-xref aoid="IsStringPrefix" id=""><a href="#sec-isstringprefix">IsStringPrefix</a></emu-xref>(<var>px</var>, <var>py</var>) is <emu-val>true</emu-val>, return <emu-val>true</emu-val>.</li><li>Let <var>k</var> be the smallest non-negative <emu-xref href="#integer" id=""><a href="#integer">integer</a></emu-xref> such that the code unit at index <var>k</var> within <var>px</var> is different from the code unit at index <var>k</var> within <var>py</var>. (There must be such a <var>k</var>, for neither String is a prefix of the other.)</li><li>Let <var>m</var> be the <emu-xref href="#integer" id=""><a href="#integer">integer</a></emu-xref> that is the numeric value of the code unit at index <var>k</var> within <var>px</var>.</li><li>Let <var>n</var> be the <emu-xref href="#integer" id=""><a href="#integer">integer</a></emu-xref> that is the numeric value of the code unit at index <var>k</var> within <var>py</var>.</li><li>If <var>m</var> &lt; <var>n</var>, return <emu-val>true</emu-val>. Otherwise, return <emu-val>false</emu-val>.</li></ol></li><li>Else,<ol><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>px</var>) is BigInt and <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>py</var>) is String, then<ol><li>Let <var>ny</var> be !&nbsp;<emu-xref aoid="StringToBigInt" id=""><a href="#sec-stringtobigint">StringToBigInt</a></emu-xref>(<var>py</var>).</li><li>If <var>ny</var> is <emu-val>NaN</emu-val>, return <emu-val>undefined</emu-val>.</li><li>Return <emu-xref aoid="BigInt::lessThan" id=""><a href="#sec-numeric-types-bigint-lessThan">BigInt::lessThan</a></emu-xref>(<var>px</var>, <var>ny</var>).</li></ol></li><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>px</var>) is String and <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>py</var>) is BigInt, then<ol><li>Let <var>nx</var> be !&nbsp;<emu-xref aoid="StringToBigInt" id=""><a href="#sec-stringtobigint">StringToBigInt</a></emu-xref>(<var>px</var>).</li><li>If <var>nx</var> is <emu-val>NaN</emu-val>, return <emu-val>undefined</emu-val>.</li><li>Return <emu-xref aoid="BigInt::lessThan" id=""><a href="#sec-numeric-types-bigint-lessThan">BigInt::lessThan</a></emu-xref>(<var>nx</var>, <var>py</var>).</li></ol></li><li>NOTE: Because <var>px</var> and <var>py</var> are primitive values, evaluation order is not important.</li><li>Let <var>nx</var> be ?&nbsp;<emu-xref aoid="ToNumeric" id=""><a href="#sec-tonumeric">ToNumeric</a></emu-xref>(<var>px</var>).</li><li>Let <var>ny</var> be ?&nbsp;<emu-xref aoid="ToNumeric" id=""><a href="#sec-tonumeric">ToNumeric</a></emu-xref>(<var>py</var>).</li><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>nx</var>) is the same as <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>ny</var>), return <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>nx</var>)::lessThan(<var>nx</var>, <var>ny</var>).</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>nx</var>) is BigInt and <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>ny</var>) is Number, or <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>nx</var>) is Number and <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>ny</var>) is BigInt.</li><li>If <var>nx</var> or <var>ny</var> is <emu-val>NaN</emu-val>, return <emu-val>undefined</emu-val>.</li><li>If <var>nx</var> is <emu-val>-∞</emu-val><sub>𝔽</sub> or <var>ny</var> is <emu-val>+∞</emu-val><sub>𝔽</sub>, return <emu-val>true</emu-val>.</li><li>If <var>nx</var> is <emu-val>+∞</emu-val><sub>𝔽</sub> or <var>ny</var> is <emu-val>-∞</emu-val><sub>𝔽</sub>, return <emu-val>false</emu-val>.</li><li>If <emu-xref href="#ℝ" id=""><a href="#ℝ">ℝ</a></emu-xref>(<var>nx</var>) &lt; <emu-xref href="#ℝ" id=""><a href="#ℝ">ℝ</a></emu-xref>(<var>ny</var>), return <emu-val>true</emu-val>; otherwise return <emu-val>false</emu-val>.</li></ol></li></ol></emu-alg>
       <emu-note><span class="note">Note 1</span><div class="note-contents">
@@ -4726,3 +4727,3 @@
       <h1><span class="secnum">7.3.11</span> HasProperty ( <var>O</var>, <var>P</var> )</h1>
-      <p>The abstract operation HasProperty takes arguments <var>O</var> (an Object) and <var>P</var> (a property key) and returns a completion record which, if its [[Type]] is <emu-const>normal</emu-const>, has a [[Value]] which is a Boolean. It is used to determine whether an object has a property with the specified property key. The property may be either an own or inherited. It performs the following steps when called:</p>
+      <p>The abstract operation HasProperty takes arguments <var>O</var> (an Object) and <var>P</var> (a property key). It returns a completion record which, if its [[Type]] is <emu-const>normal</emu-const>, has a [[Value]] which is a Boolean. It is used to determine whether an object has a property with the specified property key. The property may be either an own or inherited. It performs the following steps when called:</p>
       <emu-alg><ol><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>O</var>) is Object.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <emu-xref aoid="IsPropertyKey" id=""><a href="#sec-ispropertykey">IsPropertyKey</a></emu-xref>(<var>P</var>) is <emu-val>true</emu-val>.</li><li>Return ? <var>O</var>.[[HasProperty]](<var>P</var>).</li></ol></emu-alg>
@@ -4732,3 +4733,3 @@
       <h1><span class="secnum">7.3.12</span> HasOwnProperty ( <var>O</var>, <var>P</var> )</h1>
-      <p>The abstract operation HasOwnProperty takes arguments <var>O</var> (an Object) and <var>P</var> (a property key) and returns a completion record which, if its [[Type]] is <emu-const>normal</emu-const>, has a [[Value]] which is a Boolean. It is used to determine whether an object has an own property with the specified property key. It performs the following steps when called:</p>
+      <p>The abstract operation HasOwnProperty takes arguments <var>O</var> (an Object) and <var>P</var> (a property key). It returns a completion record which, if its [[Type]] is <emu-const>normal</emu-const>, has a [[Value]] which is a Boolean. It is used to determine whether an object has an own property with the specified property key. It performs the following steps when called:</p>
       <emu-alg><ol><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>O</var>) is Object.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <emu-xref aoid="IsPropertyKey" id=""><a href="#sec-ispropertykey">IsPropertyKey</a></emu-xref>(<var>P</var>) is <emu-val>true</emu-val>.</li><li>Let <var>desc</var> be ? <var>O</var>.[[GetOwnProperty]](<var>P</var>).</li><li>If <var>desc</var> is <emu-val>undefined</emu-val>, return <emu-val>false</emu-val>.</li><li>Return <emu-val>true</emu-val>.</li></ol></emu-alg>
@@ -12443,3 +12444,3 @@
         <h1><span class="secnum">10.4.5.6</span> [[Delete]] ( <var>P</var> )</h1>
-        <p>The [[Delete]] internal method of an <emu-xref href="#integer-indexed-exotic-object" id=""><a href="#integer-indexed-exotic-object">Integer-Indexed exotic object</a></emu-xref> <var>O</var> takes arguments <var>P</var> (a property key). It performs the following steps when called:</p>
+        <p>The [[Delete]] internal method of an <emu-xref href="#integer-indexed-exotic-object" id=""><a href="#integer-indexed-exotic-object">Integer-Indexed exotic object</a></emu-xref> <var>O</var> takes argument <var>P</var> (a property key). It performs the following steps when called:</p>
         <emu-alg><ol><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <emu-xref aoid="IsPropertyKey" id=""><a href="#sec-ispropertykey">IsPropertyKey</a></emu-xref>(<var>P</var>) is <emu-val>true</emu-val>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>O</var> is an <emu-xref href="#integer-indexed-exotic-object" id=""><a href="#integer-indexed-exotic-object">Integer-Indexed exotic object</a></emu-xref>.</li><li>If <emu-xref aoid="Type" id=""><a href="#sec-ecmascript-data-types-and-values">Type</a></emu-xref>(<var>P</var>) is String, then<ol><li>Let <var>numericIndex</var> be !&nbsp;<emu-xref aoid="CanonicalNumericIndexString" id=""><a href="#sec-canonicalnumericindexstring">CanonicalNumericIndexString</a></emu-xref>(<var>P</var>).</li><li>If <var>numericIndex</var> is not <emu-val>undefined</emu-val>, then<ol><li>If !&nbsp;<emu-xref aoid="IsValidIntegerIndex" id=""><a href="#sec-isvalidintegerindex">IsValidIntegerIndex</a></emu-xref>(<var>O</var>, <var>numericIndex</var>) is <emu-val>false</emu-val>, return <emu-val>true</emu-val>; else return <emu-val>false</emu-val>.</li></ol></li></ol></li><li>Return ?&nbsp;<emu-xref aoid="OrdinaryDelete" id=""><a href="#sec-ordinarydelete">OrdinaryDelete</a></emu-xref>(<var>O</var>, <var>P</var>).</li></ol></emu-alg>
@@ -26116,3 +26117,3 @@
                 <td>
-                  <emu-xref aoid="InitializeEnvironment" id=""><a href="#sec-source-text-module-record-initialize-environment">InitializeEnvironment</a></emu-xref>()
+                  InitializeEnvironment()
                 </td>
@@ -26124,3 +26125,3 @@
                 <td>
-                  <emu-xref aoid="ExecuteModule" id=""><a href="#sec-source-text-module-record-execute-module">ExecuteModule</a></emu-xref>()
+                  ExecuteModule()
                 </td>
@@ -26144,3 +26145,3 @@
 
-            <emu-alg><ol><li>If <var>module</var> is not a <emu-xref href="#cyclic-module-record" id=""><a href="#cyclic-module-record">Cyclic Module Record</a></emu-xref>, then<ol><li>Perform ? <var>module</var>.Link().</li><li>Return <var>index</var>.</li></ol></li><li>If <var>module</var>.[[Status]] is <emu-const>linking</emu-const>, <emu-const>linked</emu-const>, or <emu-const>evaluated</emu-const>, then<ol><li>Return <var>index</var>.</li></ol></li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>module</var>.[[Status]] is <emu-const>unlinked</emu-const>.</li><li>Set <var>module</var>.[[Status]] to <emu-const>linking</emu-const>.</li><li>Set <var>module</var>.[[DFSIndex]] to <var>index</var>.</li><li>Set <var>module</var>.[[DFSAncestorIndex]] to <var>index</var>.</li><li>Set <var>index</var> to <var>index</var> + 1.</li><li>Append <var>module</var> to <var>stack</var>.</li><li>For each String <var>required</var> of <var>module</var>.[[RequestedModules]], do<ol><li>Let <var>requiredModule</var> be ?&nbsp;<emu-xref aoid="HostResolveImportedModule" id=""><a href="#sec-hostresolveimportedmodule">HostResolveImportedModule</a></emu-xref>(<var>module</var>, <var>required</var>).</li><li>Set <var>index</var> to ?&nbsp;<emu-xref aoid="InnerModuleLinking" id=""><a href="#sec-InnerModuleLinking">InnerModuleLinking</a></emu-xref>(<var>requiredModule</var>, <var>stack</var>, <var>index</var>).</li><li>If <var>requiredModule</var> is a <emu-xref href="#cyclic-module-record" id=""><a href="#cyclic-module-record">Cyclic Module Record</a></emu-xref>, then<ol><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>requiredModule</var>.[[Status]] is either <emu-const>linking</emu-const>, <emu-const>linked</emu-const>, or <emu-const>evaluated</emu-const>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>requiredModule</var>.[[Status]] is <emu-const>linking</emu-const> if and only if <var>requiredModule</var> is in <var>stack</var>.</li><li>If <var>requiredModule</var>.[[Status]] is <emu-const>linking</emu-const>, then<ol><li>Set <var>module</var>.[[DFSAncestorIndex]] to <emu-xref aoid="min" id=""><a href="#eqn-min">min</a></emu-xref>(<var>module</var>.[[DFSAncestorIndex]], <var>requiredModule</var>.[[DFSAncestorIndex]]).</li></ol></li></ol></li></ol></li><li>Perform ? <var>module</var>.<emu-xref aoid="InitializeEnvironment" id=""><a href="#sec-source-text-module-record-initialize-environment">InitializeEnvironment</a></emu-xref>().</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>module</var> occurs exactly once in <var>stack</var>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>module</var>.[[DFSAncestorIndex]] ≤ <var>module</var>.[[DFSIndex]].</li><li>If <var>module</var>.[[DFSAncestorIndex]] = <var>module</var>.[[DFSIndex]], then<ol><li>Let <var>done</var> be <emu-val>false</emu-val>.</li><li>Repeat, while <var>done</var> is <emu-val>false</emu-val>,<ol><li>Let <var>requiredModule</var> be the last element in <var>stack</var>.</li><li>Remove the last element of <var>stack</var>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>requiredModule</var> is a <emu-xref href="#cyclic-module-record" id=""><a href="#cyclic-module-record">Cyclic Module Record</a></emu-xref>.</li><li>Set <var>requiredModule</var>.[[Status]] to <emu-const>linked</emu-const>.</li><li>If <var>requiredModule</var> and <var>module</var> are the same <emu-xref href="#sec-abstract-module-records" id=""><a href="#sec-abstract-module-records">Module Record</a></emu-xref>, set <var>done</var> to <emu-val>true</emu-val>.</li></ol></li></ol></li><li>Return <var>index</var>.</li></ol></emu-alg>
+            <emu-alg><ol><li>If <var>module</var> is not a <emu-xref href="#cyclic-module-record" id=""><a href="#cyclic-module-record">Cyclic Module Record</a></emu-xref>, then<ol><li>Perform ? <var>module</var>.Link().</li><li>Return <var>index</var>.</li></ol></li><li>If <var>module</var>.[[Status]] is <emu-const>linking</emu-const>, <emu-const>linked</emu-const>, or <emu-const>evaluated</emu-const>, then<ol><li>Return <var>index</var>.</li></ol></li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>module</var>.[[Status]] is <emu-const>unlinked</emu-const>.</li><li>Set <var>module</var>.[[Status]] to <emu-const>linking</emu-const>.</li><li>Set <var>module</var>.[[DFSIndex]] to <var>index</var>.</li><li>Set <var>module</var>.[[DFSAncestorIndex]] to <var>index</var>.</li><li>Set <var>index</var> to <var>index</var> + 1.</li><li>Append <var>module</var> to <var>stack</var>.</li><li>For each String <var>required</var> of <var>module</var>.[[RequestedModules]], do<ol><li>Let <var>requiredModule</var> be ?&nbsp;<emu-xref aoid="HostResolveImportedModule" id=""><a href="#sec-hostresolveimportedmodule">HostResolveImportedModule</a></emu-xref>(<var>module</var>, <var>required</var>).</li><li>Set <var>index</var> to ?&nbsp;<emu-xref aoid="InnerModuleLinking" id=""><a href="#sec-InnerModuleLinking">InnerModuleLinking</a></emu-xref>(<var>requiredModule</var>, <var>stack</var>, <var>index</var>).</li><li>If <var>requiredModule</var> is a <emu-xref href="#cyclic-module-record" id=""><a href="#cyclic-module-record">Cyclic Module Record</a></emu-xref>, then<ol><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>requiredModule</var>.[[Status]] is either <emu-const>linking</emu-const>, <emu-const>linked</emu-const>, or <emu-const>evaluated</emu-const>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>requiredModule</var>.[[Status]] is <emu-const>linking</emu-const> if and only if <var>requiredModule</var> is in <var>stack</var>.</li><li>If <var>requiredModule</var>.[[Status]] is <emu-const>linking</emu-const>, then<ol><li>Set <var>module</var>.[[DFSAncestorIndex]] to <emu-xref aoid="min" id=""><a href="#eqn-min">min</a></emu-xref>(<var>module</var>.[[DFSAncestorIndex]], <var>requiredModule</var>.[[DFSAncestorIndex]]).</li></ol></li></ol></li></ol></li><li>Perform ? <var>module</var>.InitializeEnvironment().</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>module</var> occurs exactly once in <var>stack</var>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>module</var>.[[DFSAncestorIndex]] ≤ <var>module</var>.[[DFSIndex]].</li><li>If <var>module</var>.[[DFSAncestorIndex]] = <var>module</var>.[[DFSIndex]], then<ol><li>Let <var>done</var> be <emu-val>false</emu-val>.</li><li>Repeat, while <var>done</var> is <emu-val>false</emu-val>,<ol><li>Let <var>requiredModule</var> be the last element in <var>stack</var>.</li><li>Remove the last element of <var>stack</var>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>requiredModule</var> is a <emu-xref href="#cyclic-module-record" id=""><a href="#cyclic-module-record">Cyclic Module Record</a></emu-xref>.</li><li>Set <var>requiredModule</var>.[[Status]] to <emu-const>linked</emu-const>.</li><li>If <var>requiredModule</var> and <var>module</var> are the same <emu-xref href="#sec-abstract-module-records" id=""><a href="#sec-abstract-module-records">Module Record</a></emu-xref>, set <var>done</var> to <emu-val>true</emu-val>.</li></ol></li></ol></li><li>Return <var>index</var>.</li></ol></emu-alg>
           </emu-clause>
@@ -26158,3 +26159,3 @@
 
-            <emu-alg><ol><li>If <var>module</var> is not a <emu-xref href="#cyclic-module-record" id=""><a href="#cyclic-module-record">Cyclic Module Record</a></emu-xref>, then<ol><li>Perform ? <var>module</var>.Evaluate().</li><li>Return <var>index</var>.</li></ol></li><li>If <var>module</var>.[[Status]] is <emu-const>evaluated</emu-const>, then<ol><li>If <var>module</var>.[[EvaluationError]] is <emu-val>undefined</emu-val>, return <var>index</var>.</li><li>Otherwise, return <var>module</var>.[[EvaluationError]].</li></ol></li><li>If <var>module</var>.[[Status]] is <emu-const>evaluating</emu-const>, return <var>index</var>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>module</var>.[[Status]] is <emu-const>linked</emu-const>.</li><li>Set <var>module</var>.[[Status]] to <emu-const>evaluating</emu-const>.</li><li>Set <var>module</var>.[[DFSIndex]] to <var>index</var>.</li><li>Set <var>module</var>.[[DFSAncestorIndex]] to <var>index</var>.</li><li>Set <var>index</var> to <var>index</var> + 1.</li><li>Append <var>module</var> to <var>stack</var>.</li><li>For each String <var>required</var> of <var>module</var>.[[RequestedModules]], do<ol><li>Let <var>requiredModule</var> be !&nbsp;<emu-xref aoid="HostResolveImportedModule" id=""><a href="#sec-hostresolveimportedmodule">HostResolveImportedModule</a></emu-xref>(<var>module</var>, <var>required</var>).</li><li>NOTE: Link must be completed successfully prior to invoking this method, so every requested module is guaranteed to resolve successfully.</li><li>Set <var>index</var> to ?&nbsp;<emu-xref aoid="InnerModuleEvaluation" id=""><a href="#sec-innermoduleevaluation">InnerModuleEvaluation</a></emu-xref>(<var>requiredModule</var>, <var>stack</var>, <var>index</var>).</li><li>If <var>requiredModule</var> is a <emu-xref href="#cyclic-module-record" id=""><a href="#cyclic-module-record">Cyclic Module Record</a></emu-xref>, then<ol><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>requiredModule</var>.[[Status]] is either <emu-const>evaluating</emu-const> or <emu-const>evaluated</emu-const>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>requiredModule</var>.[[Status]] is <emu-const>evaluating</emu-const> if and only if <var>requiredModule</var> is in <var>stack</var>.</li><li>If <var>requiredModule</var>.[[Status]] is <emu-const>evaluating</emu-const>, then<ol><li>Set <var>module</var>.[[DFSAncestorIndex]] to <emu-xref aoid="min" id=""><a href="#eqn-min">min</a></emu-xref>(<var>module</var>.[[DFSAncestorIndex]], <var>requiredModule</var>.[[DFSAncestorIndex]]).</li></ol></li></ol></li></ol></li><li>Perform ? <var>module</var>.<emu-xref aoid="ExecuteModule" id=""><a href="#sec-source-text-module-record-execute-module">ExecuteModule</a></emu-xref>().</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>module</var> occurs exactly once in <var>stack</var>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>module</var>.[[DFSAncestorIndex]] ≤ <var>module</var>.[[DFSIndex]].</li><li>If <var>module</var>.[[DFSAncestorIndex]] = <var>module</var>.[[DFSIndex]], then<ol><li>Let <var>done</var> be <emu-val>false</emu-val>.</li><li>Repeat, while <var>done</var> is <emu-val>false</emu-val>,<ol><li>Let <var>requiredModule</var> be the last element in <var>stack</var>.</li><li>Remove the last element of <var>stack</var>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>requiredModule</var> is a <emu-xref href="#cyclic-module-record" id=""><a href="#cyclic-module-record">Cyclic Module Record</a></emu-xref>.</li><li>Set <var>requiredModule</var>.[[Status]] to <emu-const>evaluated</emu-const>.</li><li>If <var>requiredModule</var> and <var>module</var> are the same <emu-xref href="#sec-abstract-module-records" id=""><a href="#sec-abstract-module-records">Module Record</a></emu-xref>, set <var>done</var> to <emu-val>true</emu-val>.</li></ol></li></ol></li><li>Return <var>index</var>.</li></ol></emu-alg>
+            <emu-alg><ol><li>If <var>module</var> is not a <emu-xref href="#cyclic-module-record" id=""><a href="#cyclic-module-record">Cyclic Module Record</a></emu-xref>, then<ol><li>Perform ? <var>module</var>.Evaluate().</li><li>Return <var>index</var>.</li></ol></li><li>If <var>module</var>.[[Status]] is <emu-const>evaluated</emu-const>, then<ol><li>If <var>module</var>.[[EvaluationError]] is <emu-val>undefined</emu-val>, return <var>index</var>.</li><li>Otherwise, return <var>module</var>.[[EvaluationError]].</li></ol></li><li>If <var>module</var>.[[Status]] is <emu-const>evaluating</emu-const>, return <var>index</var>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>module</var>.[[Status]] is <emu-const>linked</emu-const>.</li><li>Set <var>module</var>.[[Status]] to <emu-const>evaluating</emu-const>.</li><li>Set <var>module</var>.[[DFSIndex]] to <var>index</var>.</li><li>Set <var>module</var>.[[DFSAncestorIndex]] to <var>index</var>.</li><li>Set <var>index</var> to <var>index</var> + 1.</li><li>Append <var>module</var> to <var>stack</var>.</li><li>For each String <var>required</var> of <var>module</var>.[[RequestedModules]], do<ol><li>Let <var>requiredModule</var> be !&nbsp;<emu-xref aoid="HostResolveImportedModule" id=""><a href="#sec-hostresolveimportedmodule">HostResolveImportedModule</a></emu-xref>(<var>module</var>, <var>required</var>).</li><li>NOTE: Link must be completed successfully prior to invoking this method, so every requested module is guaranteed to resolve successfully.</li><li>Set <var>index</var> to ?&nbsp;<emu-xref aoid="InnerModuleEvaluation" id=""><a href="#sec-innermoduleevaluation">InnerModuleEvaluation</a></emu-xref>(<var>requiredModule</var>, <var>stack</var>, <var>index</var>).</li><li>If <var>requiredModule</var> is a <emu-xref href="#cyclic-module-record" id=""><a href="#cyclic-module-record">Cyclic Module Record</a></emu-xref>, then<ol><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>requiredModule</var>.[[Status]] is either <emu-const>evaluating</emu-const> or <emu-const>evaluated</emu-const>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>requiredModule</var>.[[Status]] is <emu-const>evaluating</emu-const> if and only if <var>requiredModule</var> is in <var>stack</var>.</li><li>If <var>requiredModule</var>.[[Status]] is <emu-const>evaluating</emu-const>, then<ol><li>Set <var>module</var>.[[DFSAncestorIndex]] to <emu-xref aoid="min" id=""><a href="#eqn-min">min</a></emu-xref>(<var>module</var>.[[DFSAncestorIndex]], <var>requiredModule</var>.[[DFSAncestorIndex]]).</li></ol></li></ol></li></ol></li><li>Perform ? <var>module</var>.ExecuteModule().</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>module</var> occurs exactly once in <var>stack</var>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>module</var>.[[DFSAncestorIndex]] ≤ <var>module</var>.[[DFSIndex]].</li><li>If <var>module</var>.[[DFSAncestorIndex]] = <var>module</var>.[[DFSIndex]], then<ol><li>Let <var>done</var> be <emu-val>false</emu-val>.</li><li>Repeat, while <var>done</var> is <emu-val>false</emu-val>,<ol><li>Let <var>requiredModule</var> be the last element in <var>stack</var>.</li><li>Remove the last element of <var>stack</var>.</li><li><emu-xref href="#assert" id=""><a href="#assert">Assert</a></emu-xref>: <var>requiredModule</var> is a <emu-xref href="#cyclic-module-record" id=""><a href="#cyclic-module-record">Cyclic Module Record</a></emu-xref>.</li><li>Set <var>requiredModule</var>.[[Status]] to <emu-const>evaluated</emu-const>.</li><li>If <var>requiredModule</var> and <var>module</var> are the same <emu-xref href="#sec-abstract-module-records" id=""><a href="#sec-abstract-module-records">Module Record</a></emu-xref>, set <var>done</var> to <emu-val>true</emu-val>.</li></ol></li></ol></li><li>Return <var>index</var>.</li></ol></emu-alg>
           </emu-clause>
@@ -26199,3 +26200,3 @@
 
-          <p>Now consider a case where <var>A</var> has an linking error; for example, it tries to import a binding from <var>C</var> that does not exist. In that case, the above steps still occur, including the early return from the second call to <emu-xref aoid="InnerModuleLinking" id=""><a href="#sec-InnerModuleLinking">InnerModuleLinking</a></emu-xref> on <var>A</var>. However, once we unwind back to the original <emu-xref aoid="InnerModuleLinking" id=""><a href="#sec-InnerModuleLinking">InnerModuleLinking</a></emu-xref> on <var>A</var>, it fails during <emu-xref aoid="InitializeEnvironment" id=""><a href="#sec-source-text-module-record-initialize-environment">InitializeEnvironment</a></emu-xref>, namely right after <var>C</var>.ResolveExport(). The thrown <emu-val>SyntaxError</emu-val> exception propagates up to <var>A</var>.Link, which resets all modules that are currently on its <var>stack</var> (these are always exactly the modules that are still <emu-const>linking</emu-const>). Hence both <var>A</var> and <var>B</var> become <emu-const>unlinked</emu-const>. Note that <var>C</var> is left as <emu-const>linked</emu-const>.</p>
+          <p>Now consider a case where <var>A</var> has an linking error; for example, it tries to import a binding from <var>C</var> that does not exist. In that case, the above steps still occur, including the early return from the second call to <emu-xref aoid="InnerModuleLinking" id=""><a href="#sec-InnerModuleLinking">InnerModuleLinking</a></emu-xref> on <var>A</var>. However, once we unwind back to the original <emu-xref aoid="InnerModuleLinking" id=""><a href="#sec-InnerModuleLinking">InnerModuleLinking</a></emu-xref> on <var>A</var>, it fails during InitializeEnvironment, namely right after <var>C</var>.ResolveExport(). The thrown <emu-val>SyntaxError</emu-val> exception propagates up to <var>A</var>.Link, which resets all modules that are currently on its <var>stack</var> (these are always exactly the modules that are still <emu-const>linking</emu-const>). Hence both <var>A</var> and <var>B</var> become <emu-const>unlinked</emu-const>. Note that <var>C</var> is left as <emu-const>linked</emu-const>.</p>
 
@@ -26726,5 +26727,7 @@
           <p>The ResolveExport concrete method of a <emu-xref href="#sourctextmodule-record" id=""><a href="#sourctextmodule-record">Source Text Module Record</a></emu-xref> <var>module</var> takes argument <var>exportName</var> (a String) and optional argument <var>resolveSet</var>.</p>
-          <p>ResolveExport attempts to resolve an imported binding to the actual defining module and local binding name. The defining module may be the module represented by the <emu-xref href="#sec-abstract-module-records" id=""><a href="#sec-abstract-module-records">Module Record</a></emu-xref> this method was invoked on or some other module that is imported by that module. The parameter <var>resolveSet</var> is used to detect unresolved circular import/export paths. If a pair consisting of specific <emu-xref href="#sec-abstract-module-records" id=""><a href="#sec-abstract-module-records">Module Record</a></emu-xref> and <var>exportName</var> is reached that is already in <var>resolveSet</var>, an import circularity has been encountered. Before recursively calling ResolveExport, a pair consisting of <var>module</var> and <var>exportName</var> is added to <var>resolveSet</var>.</p>
-          <p>If a defining module is found, a <emu-xref href="#resolvedbinding-record" id=""><a href="#resolvedbinding-record">ResolvedBinding Record</a></emu-xref> { [[Module]], [[BindingName]] } is returned. This record identifies the resolved binding of the originally requested export, unless this is the export of a namespace with no local binding. In this case, [[BindingName]] will be set to <emu-val>"*namespace*"</emu-val>. If no definition was found or the request is found to be circular, <emu-val>null</emu-val> is returned. If the request is found to be ambiguous, the string <emu-val>"ambiguous"</emu-val> is returned.</p>
-          <p>This concrete method performs the following steps when called:</p>
+              <p>ResolveExport attempts to resolve an imported binding to the actual defining module and local binding name. The defining module may be the module represented by the <emu-xref href="#sec-abstract-module-records" id=""><a href="#sec-abstract-module-records">Module Record</a></emu-xref> this method was invoked on or some other module that is imported by that module. The parameter <var>resolveSet</var> is used to detect unresolved circular import/export paths. If a pair consisting of specific <emu-xref href="#sec-abstract-module-records" id=""><a href="#sec-abstract-module-records">Module Record</a></emu-xref> and <var>exportName</var> is reached that is already in <var>resolveSet</var>, an import circularity has been encountered. Before recursively calling ResolveExport, a pair consisting of <var>module</var> and <var>exportName</var> is added to <var>resolveSet</var>.</p>
+              <p>If a defining module is found, a <emu-xref href="#resolvedbinding-record" id=""><a href="#resolvedbinding-record">ResolvedBinding Record</a></emu-xref> { [[Module]], [[BindingName]] } is returned. This record identifies the resolved binding of the originally requested export, unless this is the export of a namespace with no local binding. In this case, [[BindingName]] will be set to <emu-val>"*namespace*"</emu-val>. If no definition was found or the request is found to be circular, <emu-val>null</emu-val> is returned. If the request is found to be ambiguous, the string <emu-val>"ambiguous"</emu-val> is returned.</p>
+            
+
+          <p>It performs the following steps when called:</p>
 
@@ -26733,3 +26736,3 @@
 
-        <emu-clause id="sec-source-text-module-record-initialize-environment" aoid="InitializeEnvironment">
+        <emu-clause id="sec-source-text-module-record-initialize-environment">
           <h1><span class="secnum">16.2.1.6.4</span> InitializeEnvironment ( )</h1>
@@ -26740,3 +26743,3 @@
 
-        <emu-clause id="sec-source-text-module-record-execute-module" aoid="ExecuteModule">
+        <emu-clause id="sec-source-text-module-record-execute-module">
           <h1><span class="secnum">16.2.1.6.5</span> ExecuteModule ( )</h1>
@@ -29974,3 +29977,3 @@
         <p>When the <code>Math.pow</code> method is called with arguments <var>base</var> and <var>exponent</var>, the following steps are taken:</p>
-        <emu-alg><ol><li>Set <var>base</var> to ?&nbsp;<emu-xref aoid="ToNumber" id=""><a href="#sec-tonumber">ToNumber</a></emu-xref>(<var>base</var>).</li><li>Set <var>exponent</var> to ?&nbsp;<emu-xref aoid="ToNumber" id=""><a href="#sec-tonumber">ToNumber</a></emu-xref>(<var>exponent</var>).</li><li>Return ! Number::exponentiate(<var>base</var>, <var>exponent</var>).</li></ol></emu-alg>
+        <emu-alg><ol><li>Set <var>base</var> to ?&nbsp;<emu-xref aoid="ToNumber" id=""><a href="#sec-tonumber">ToNumber</a></emu-xref>(<var>base</var>).</li><li>Set <var>exponent</var> to ?&nbsp;<emu-xref aoid="ToNumber" id=""><a href="#sec-tonumber">ToNumber</a></emu-xref>(<var>exponent</var>).</li><li>Return ! <emu-xref aoid="Number::exponentiate" id=""><a href="#sec-numeric-types-number-exponentiate">Number::exponentiate</a></emu-xref>(<var>base</var>, <var>exponent</var>).</li></ol></emu-alg>
       </emu-clause>

jmdyck added a commit to jmdyck/ecma262 that referenced this pull request Jul 15, 2021
for:
 - abstract operations
 - numeric methods
 - 'concrete' methods
 - internal methods
@jmdyck jmdyck force-pushed the operation_headers branch from da85f72 to d39343e Compare July 15, 2021 00:56
@michaelficarra michaelficarra added the ready to merge Editors believe this PR needs no further reviews, and is ready to land. label Jul 15, 2021
for:
 - abstract operations
 - numeric methods
 - 'concrete' methods
 - internal methods
@ljharb ljharb force-pushed the operation_headers branch from d39343e to f64df56 Compare July 15, 2021 03:26
@ljharb ljharb merged commit f64df56 into tc39:master Jul 15, 2021
@jmdyck jmdyck deleted the operation_headers branch July 18, 2021 17:18
jmdyck added a commit to jmdyck/ecma262 that referenced this pull request Sep 14, 2021
PR tc39#2483 dropped "either" when transferring from Assert to param-type,
but didin't touch occurrences of "either" that were already there (from PR tc39#545).
This commit eliminates the latter.
ljharb pushed a commit to jmdyck/ecma262 that referenced this pull request Sep 14, 2021
PR tc39#2483 dropped "either" when transferring from Assert to param-type, but didn't touch occurrences of "either" that were already there (from PR tc39#545).
This commit eliminates the latter.
mathiasbynens pushed a commit to mathiasbynens/ecma262 that referenced this pull request Oct 18, 2021
for:
 - abstract operations
 - numeric methods
 - 'concrete' methods
 - internal methods
mathiasbynens pushed a commit to mathiasbynens/ecma262 that referenced this pull request Oct 18, 2021
PR tc39#2483 dropped "either" when transferring from Assert to param-type, but didn't touch occurrences of "either" that were already there (from PR tc39#545).
This commit eliminates the latter.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
completion records Relates to completion records, and ? / ! notation. editorial change ready to merge Editors believe this PR needs no further reviews, and is ready to land.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants