From 88bd90380d9e6110947bb086ed581ed9262de330 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Wed, 21 Jul 2021 21:55:24 -0700 Subject: [PATCH 1/2] Editorial: add "Legacy" section (#2125) - co-opts prose from Annex B description - dfn legacy and add emu-not-ref where appropriate - use dash in IDs - don't legacy; clauses are what is legacy Co-authored-by: Jordan Harband Co-authored-by: Michael Ficarra --- spec.html | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/spec.html b/spec.html index 279a84d353..99ae19e4d9 100644 --- a/spec.html +++ b/spec.html @@ -128,8 +128,17 @@

Conformance

A conforming implementation of ECMAScript must not implement any extension that is listed as a Forbidden Extension in subclause .

A conforming implementation of ECMAScript must not redefine any facilities that are not implementation-defined, implementation-approximated, or host-defined.

A conforming implementation of ECMAScript may choose to implement or not implement Normative Optional subclauses. If any Normative Optional behaviour is implemented, all of the behaviour in the containing Normative Optional clause must be implemented. A Normative Optional clause is denoted in this specification with the words "Normative Optional" in a coloured box, as shown below.

- -

Example Clause Heading

+ +

Example Normative Optional Clause Heading

+

Example clause contents.

+
+

A conforming implementation of ECMAScript must implement Legacy subclauses, unless they are also marked as Normative Optional. All of the language features and behaviours specified within Legacy subclauses have one or more undesirable characteristics. However, their continued usage in existing applications prevents their removal from this specification. These features are not considered part of the core ECMAScript language. Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code.

+ +

Example Legacy Clause Heading

+

Example clause contents.

+
+ +

Example Legacy Normative Optional Clause Heading

Example clause contents.

From 1d70aa7c391f8487284d3330b7a27889b7d867c8 Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Wed, 21 Jul 2021 21:55:26 -0700 Subject: [PATCH 2/2] Normative: move __proto__ out of annex b (#2125) Co-authored-by: Gus Caplan Co-authored-by: Jordan Harband Co-authored-by: Michael Dyck --- spec.html | 267 ++++++++++++++++++++++++------------------------------ 1 file changed, 120 insertions(+), 147 deletions(-) diff --git a/spec.html b/spec.html index 99ae19e4d9..223b839bb0 100644 --- a/spec.html +++ b/spec.html @@ -17744,7 +17744,7 @@

Syntax

In certain contexts, |ObjectLiteral| is used as a cover grammar for a more restricted secondary grammar. The |CoverInitializedName| production is necessary to fully cover these secondary grammars. However, use of this production results in an early Syntax Error in normal contexts where an actual |ObjectLiteral| is expected.

- +

Static Semantics: Early Errors

PropertyDefinition : MethodDefinition
    @@ -17765,6 +17765,19 @@

    Static Semantics: Early Errors

    This production exists so that |ObjectLiteral| can serve as a cover grammar for |ObjectAssignmentPattern|. It cannot occur in an actual object initializer.

    + + ObjectLiteral : `{` PropertyDefinitionList `}` + + ObjectLiteral : `{` PropertyDefinitionList `,` `}` + +
      +
    • + It is a Syntax Error if PropertyNameList of |PropertyDefinitionList| contains any duplicate entries for *"__proto__"* and at least two of those entries were obtained from productions of the form PropertyDefinition : PropertyName `:` AssignmentExpression. This rule is not applied if this |PropertyDefinition| is contained within a |Script| that is being parsed for JSON.parse (see step of JSON.parse). +
    • +
    + +

    The List returned by PropertyNameList does not include property names defined using a |ComputedPropertyName|.

    +
    @@ -17860,18 +17873,25 @@

    Runtime Semantics: PropertyDefinitionEvaluation

    1. Let _propKey_ be the result of evaluating |PropertyName|. 1. ReturnIfAbrupt(_propKey_). - 1. If IsAnonymousFunctionDefinition(|AssignmentExpression|) is *true*, then + 1. If this |PropertyDefinition| is contained within a |Script| that is being evaluated for JSON.parse (see step of JSON.parse), then + 1. Let _isProtoSetter_ be *false*. + 1. Else if _propKey_ is the String value *"__proto__"* and if IsComputedPropertyKey of |PropertyName| is *false*, then + 1. Let _isProtoSetter_ be *true*. + 1. Else, + 1. Let _isProtoSetter_ be *false*. + 1. If IsAnonymousFunctionDefinition(|AssignmentExpression|) is *true* and _isProtoSetter_ is *false*, then 1. Let _propValue_ be ? NamedEvaluation of |AssignmentExpression| with argument _propKey_. 1. Else, 1. Let _exprValueRef_ be the result of evaluating |AssignmentExpression|. 1. Let _propValue_ be ? GetValue(_exprValueRef_). + 1. If _isProtoSetter_ is *true*, then + 1. If Type(_propValue_) is either Object or Null, then + 1. Return ! _object_.[[SetPrototypeOf]](_propValue_). + 1. Return NormalCompletion(~empty~). 1. Assert: _enumerable_ is *true*. 1. Assert: _object_ is an ordinary, extensible object with no non-configurable properties. 1. Return ! CreateDataPropertyOrThrow(_object_, _propKey_, _propValue_). - -

    An alternative semantics for this production is given in .

    -
    MethodDefinition : ClassElementName `(` UniqueFormalParameters `)` `{` FunctionBody `}` @@ -28302,7 +28322,7 @@

    Object.values ( _O_ )

    - +

    Properties of the Object Prototype Object

    The Object prototype object:

      @@ -28414,6 +28434,95 @@

      Object.prototype.valueOf ( )

      1. Return ? ToObject(*this* value). + + +

      Object.prototype.__proto__

      +

      `Object.prototype.__proto__` is an accessor property with attributes { [[Enumerable]]: *false*, [[Configurable]]: *true* }. The [[Get]] and [[Set]] attributes are defined as follows:

      + + +

      get Object.prototype.__proto__

      +

      The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps when called:

      + + 1. Let _O_ be ? ToObject(*this* value). + 1. Return ? _O_.[[GetPrototypeOf]](). + +
      + + +

      set Object.prototype.__proto__

      +

      The value of the [[Set]] attribute is a built-in function that takes an argument _proto_. It performs the following steps when called:

      + + 1. Let _O_ be ? RequireObjectCoercible(*this* value). + 1. If Type(_proto_) is neither Object nor Null, return *undefined*. + 1. If Type(_O_) is not Object, return *undefined*. + 1. Let _status_ be ? _O_.[[SetPrototypeOf]](_proto_). + 1. If _status_ is *false*, throw a *TypeError* exception. + 1. Return *undefined*. + +
      +
      + + +

      Legacy Object.prototype Accessor Methods

      + + +

      Object.prototype.__defineGetter__ ( _P_, _getter_ )

      +

      When the `__defineGetter__` method is called with arguments _P_ and _getter_, the following steps are taken:

      + + 1. Let _O_ be ? ToObject(*this* value). + 1. If IsCallable(_getter_) is *false*, throw a *TypeError* exception. + 1. Let _desc_ be PropertyDescriptor { [[Get]]: _getter_, [[Enumerable]]: *true*, [[Configurable]]: *true* }. + 1. Let _key_ be ? ToPropertyKey(_P_). + 1. Perform ? DefinePropertyOrThrow(_O_, _key_, _desc_). + 1. Return *undefined*. + +
      + + +

      Object.prototype.__defineSetter__ ( _P_, _setter_ )

      +

      When the `__defineSetter__` method is called with arguments _P_ and _setter_, the following steps are taken:

      + + 1. Let _O_ be ? ToObject(*this* value). + 1. If IsCallable(_setter_) is *false*, throw a *TypeError* exception. + 1. Let _desc_ be PropertyDescriptor { [[Set]]: _setter_, [[Enumerable]]: *true*, [[Configurable]]: *true* }. + 1. Let _key_ be ? ToPropertyKey(_P_). + 1. Perform ? DefinePropertyOrThrow(_O_, _key_, _desc_). + 1. Return *undefined*. + +
      + + +

      Object.prototype.__lookupGetter__ ( _P_ )

      +

      When the `__lookupGetter__` method is called with argument _P_, the following steps are taken:

      + + 1. Let _O_ be ? ToObject(*this* value). + 1. Let _key_ be ? ToPropertyKey(_P_). + 1. Repeat, + 1. Let _desc_ be ? _O_.[[GetOwnProperty]](_key_). + 1. If _desc_ is not *undefined*, then + 1. If IsAccessorDescriptor(_desc_) is *true*, return _desc_.[[Get]]. + 1. Return *undefined*. + 1. Set _O_ to ? _O_.[[GetPrototypeOf]](). + 1. If _O_ is *null*, return *undefined*. + +
      + + +

      Object.prototype.__lookupSetter__ ( _P_ )

      +

      When the `__lookupSetter__` method is called with argument _P_, the following steps are taken:

      + + 1. Let _O_ be ? ToObject(*this* value). + 1. Let _key_ be ? ToPropertyKey(_P_). + 1. Repeat, + 1. Let _desc_ be ? _O_.[[GetOwnProperty]](_key_). + 1. If _desc_ is not *undefined*, then + 1. If IsAccessorDescriptor(_desc_) is *true*, return _desc_.[[Set]]. + 1. Return *undefined*. + 1. Set _O_ to ? _O_.[[GetPrototypeOf]](). + 1. If _O_ is *null*, return *undefined*. + +
      +
      @@ -40567,9 +40676,11 @@

      JSON.parse ( _text_ [ , _reviver_ ] )

      1. Let _jsonString_ be ? ToString(_text_). 1. [id="step-json-parse-validate"] Parse ! StringToCodePoints(_jsonString_) as a JSON text as specified in ECMA-404. Throw a *SyntaxError* exception if it is not a valid JSON text as defined in that specification. 1. Let _scriptString_ be the string-concatenation of *"("*, _jsonString_, and *");"*. - 1. Let _script_ be ParseText(! StringToCodePoints(_scriptString_), |Script|). + 1. [id="step-json-parse-parse"] Let _script_ be ParseText(! StringToCodePoints(_scriptString_), |Script|). + 1. NOTE: The early error rules defined in have special handling for the above invocation of ParseText. 1. Assert: _script_ is a Parse Node. - 1. Let _completion_ be the result of evaluating _script_. The extended PropertyDefinitionEvaluation semantics defined in must not be used during the evaluation. + 1. [id="step-json-parse-eval"] Let _completion_ be the result of evaluating _script_. + 1. NOTE: The PropertyDefinitionEvaluation semantics defined in have special handling for the above evaluation. 1. Let _unfiltered_ be _completion_.[[Value]]. 1. [id="step-json-parse-assert-type"] Assert: _unfiltered_ is either a String, Number, Boolean, Null, or an Object that is defined by either an |ArrayLiteral| or an |ObjectLiteral|. 1. If IsCallable(_reviver_) is *true*, then @@ -40583,7 +40694,7 @@

      JSON.parse ( _text_ [ , _reviver_ ] )

      The *"length"* property of the `parse` function is *2*𝔽.

      Valid JSON text is a subset of the ECMAScript |PrimaryExpression| syntax. Step verifies that _jsonString_ conforms to that subset, and step asserts that that parsing and evaluation returns a value of an appropriate type.

      -

      However, because applies when evaluating ECMAScript source text and does not apply during `JSON.parse`, the same source text can produce different results when evaluated as a |PrimaryExpression| rather than as JSON. Furthermore, the Early Error for duplicate *"__proto__"* properties in object literals, which likewise does not apply during `JSON.parse`, means that not all texts accepted by `JSON.parse` are valid as a |PrimaryExpression|, despite matching the grammar.

      +

      However, because behaves differently during `JSON.parse`, the same source text can produce different results when evaluated as a |PrimaryExpression| rather than as JSON. Furthermore, the Early Error for duplicate *"__proto__"* properties in object literals, which likewise does not apply during `JSON.parse`, means that not all texts accepted by `JSON.parse` are valid as a |PrimaryExpression|, despite matching the grammar.

      @@ -45794,95 +45905,6 @@

      unescape ( _string_ )

      - -

      Additional Properties of the Object.prototype Object

      - - -

      Object.prototype.__proto__

      -

      `Object.prototype.__proto__` is an accessor property with attributes { [[Enumerable]]: *false*, [[Configurable]]: *true* }. The [[Get]] and [[Set]] attributes are defined as follows:

      - - -

      get Object.prototype.__proto__

      -

      The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps when called:

      - - 1. Let _O_ be ? ToObject(*this* value). - 1. Return ? _O_.[[GetPrototypeOf]](). - -
      - - -

      set Object.prototype.__proto__

      -

      The value of the [[Set]] attribute is a built-in function that takes an argument _proto_. It performs the following steps when called:

      - - 1. Let _O_ be ? RequireObjectCoercible(*this* value). - 1. If Type(_proto_) is neither Object nor Null, return *undefined*. - 1. If Type(_O_) is not Object, return *undefined*. - 1. Let _status_ be ? _O_.[[SetPrototypeOf]](_proto_). - 1. If _status_ is *false*, throw a *TypeError* exception. - 1. Return *undefined*. - -
      -
      - - -

      Object.prototype.__defineGetter__ ( _P_, _getter_ )

      -

      When the `__defineGetter__` method is called with arguments _P_ and _getter_, the following steps are taken:

      - - 1. Let _O_ be ? ToObject(*this* value). - 1. If IsCallable(_getter_) is *false*, throw a *TypeError* exception. - 1. Let _desc_ be PropertyDescriptor { [[Get]]: _getter_, [[Enumerable]]: *true*, [[Configurable]]: *true* }. - 1. Let _key_ be ? ToPropertyKey(_P_). - 1. Perform ? DefinePropertyOrThrow(_O_, _key_, _desc_). - 1. Return *undefined*. - -
      - - -

      Object.prototype.__defineSetter__ ( _P_, _setter_ )

      -

      When the `__defineSetter__` method is called with arguments _P_ and _setter_, the following steps are taken:

      - - 1. Let _O_ be ? ToObject(*this* value). - 1. If IsCallable(_setter_) is *false*, throw a *TypeError* exception. - 1. Let _desc_ be PropertyDescriptor { [[Set]]: _setter_, [[Enumerable]]: *true*, [[Configurable]]: *true* }. - 1. Let _key_ be ? ToPropertyKey(_P_). - 1. Perform ? DefinePropertyOrThrow(_O_, _key_, _desc_). - 1. Return *undefined*. - -
      - - -

      Object.prototype.__lookupGetter__ ( _P_ )

      -

      When the `__lookupGetter__` method is called with argument _P_, the following steps are taken:

      - - 1. Let _O_ be ? ToObject(*this* value). - 1. Let _key_ be ? ToPropertyKey(_P_). - 1. Repeat, - 1. Let _desc_ be ? _O_.[[GetOwnProperty]](_key_). - 1. If _desc_ is not *undefined*, then - 1. If IsAccessorDescriptor(_desc_) is *true*, return _desc_.[[Get]]. - 1. Return *undefined*. - 1. Set _O_ to ? _O_.[[GetPrototypeOf]](). - 1. If _O_ is *null*, return *undefined*. - -
      - - -

      Object.prototype.__lookupSetter__ ( _P_ )

      -

      When the `__lookupSetter__` method is called with argument _P_, the following steps are taken:

      - - 1. Let _O_ be ? ToObject(*this* value). - 1. Let _key_ be ? ToPropertyKey(_P_). - 1. Repeat, - 1. Let _desc_ be ? _O_.[[GetOwnProperty]](_key_). - 1. If _desc_ is not *undefined*, then - 1. If IsAccessorDescriptor(_desc_) is *true*, return _desc_.[[Set]]. - 1. Return *undefined*. - 1. Set _O_ to ? _O_.[[GetPrototypeOf]](). - 1. If _O_ is *null*, return *undefined*. - -
      -
      -

      Additional Properties of the String.prototype Object

      @@ -46150,55 +46172,6 @@

      RegExp.prototype.compile ( _pattern_, _flags_ )

      Other Additional Features

      - -

      __proto__ Property Names in Object Initializers

      -

      The following Early Error rule is added to those in . This rule is not applied under any of the following circumstances:

      -
        -
      • when |ObjectLiteral| appears in a context where |ObjectAssignmentPattern| is required,
      • -
      • when initially parsing a |CoverParenthesizedExpressionAndArrowParameterList| or a |CoverCallExpressionAndAsyncArrowHead|, or
      • -
      • when parsing text for JSON.parse.
      • -
      - - ObjectLiteral : - `{` PropertyDefinitionList `}` - `{` PropertyDefinitionList `,` `}` - -
        -
      • - It is a Syntax Error if PropertyNameList of |PropertyDefinitionList| contains any duplicate entries for *"__proto__"* and at least two of those entries were obtained from productions of the form PropertyDefinition : PropertyName `:` AssignmentExpression. -
      • -
      - -

      The List returned by PropertyNameList does not include string literal property names defined as using a |ComputedPropertyName|.

      -
      -

      In the PropertyDefinitionEvaluation algorithm for the production -
      - PropertyDefinition : PropertyName `:` AssignmentExpression -
      - is replaced with the following definition:

      - PropertyDefinition : PropertyName `:` AssignmentExpression - - 1. Let _propKey_ be the result of evaluating |PropertyName|. - 1. ReturnIfAbrupt(_propKey_). - 1. If _propKey_ is the String value *"__proto__"* and if IsComputedPropertyKey(|PropertyName|) is *false*, then - 1. Let _isProtoSetter_ be *true*. - 1. Else, - 1. Let _isProtoSetter_ be *false*. - 1. If IsAnonymousFunctionDefinition(|AssignmentExpression|) is *true* and _isProtoSetter_ is *false*, then - 1. Let _propValue_ be ? NamedEvaluation of |AssignmentExpression| with argument _propKey_. - 1. Else, - 1. Let _exprValueRef_ be the result of evaluating |AssignmentExpression|. - 1. Let _propValue_ be ? GetValue(_exprValueRef_). - 1. If _isProtoSetter_ is *true*, then - 1. If Type(_propValue_) is either Object or Null, then - 1. Return _object_.[[SetPrototypeOf]](_propValue_). - 1. Return NormalCompletion(~empty~). - 1. Assert: _enumerable_ is *true*. - 1. Assert: _object_ is an ordinary, extensible object with no non-configurable properties. - 1. Return ! CreateDataPropertyOrThrow(_object_, _propKey_, _propValue_). - -
      -

      Labelled Function Declarations

      Prior to ECMAScript 2015, the specification of |LabelledStatement| did not allow for the association of a statement label with a |FunctionDeclaration|. However, a labelled |FunctionDeclaration| was an allowable extension for non-strict code and most browser-hosted ECMAScript implementations supported that extension. In ECMAScript 2015 and later, the grammar production for |LabelledStatement| permits use of |FunctionDeclaration| as a |LabelledItem| but includes an Early Error rule that produces a Syntax Error if that occurs. That rule is modified with the addition of the highlighted text: