From df6e4aecf3dbeed8a973ab20b71f5e1efd3e1b6e Mon Sep 17 00:00:00 2001 From: Gus Caplan Date: Tue, 27 Oct 2020 14:18:24 -0500 Subject: [PATCH] Normative: Define default constructors using spec steps --- spec.html | 57 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 18 deletions(-) diff --git a/spec.html b/spec.html index b383aa145f4..bdc45efecd2 100644 --- a/spec.html +++ b/spec.html @@ -8211,10 +8211,13 @@

[[Call]] ( _thisArgument_, _argumentsList_ )

The [[Call]] internal method for an ECMAScript function object _F_ is called with parameters _thisArgument_ and _argumentsList_, a List of ECMAScript language values. The following steps are taken:

1. Assert: _F_ is an ECMAScript function object. - 1. If _F_.[[IsClassConstructor]] is *true*, throw a *TypeError* exception. 1. Let _callerContext_ be the running execution context. 1. Let _calleeContext_ be PrepareForOrdinaryCall(_F_, *undefined*). 1. Assert: _calleeContext_ is now the running execution context. + 1. If _F_.[[IsClassConstructor]] is *true*, then + 1. Let _error_ be a newly created *TypeError* object. + 1. Remove _calleeContext_ from the execution context stack and restore _callerContext_ as the running exceution context. + 1. Return AbruptCompletion(_error_). 1. Perform OrdinaryCallBindThis(_F_, _calleeContext_, _thisArgument_). 1. Let _result_ be OrdinaryCallEvaluateBody(_F_, _argumentsList_). 1. [id="step-call-pop-context-stack"] Remove _calleeContext_ from the execution context stack and restore _callerContext_ as the running execution context. @@ -8357,10 +8360,11 @@

%ThrowTypeError% ( )

MakeConstructor ( _F_ [ , _writablePrototype_ [ , _prototype_ ] ] )

The abstract operation MakeConstructor takes argument _F_ (a function object) and optional arguments _writablePrototype_ (a Boolean) and _prototype_ (an Object). It converts _F_ into a constructor. It performs the following steps when called:

- 1. Assert: _F_ is an ECMAScript function object. - 1. Assert: IsConstructor(_F_) is *false*. - 1. Assert: _F_ is an extensible object that does not have a *"prototype"* own property. - 1. Set _F_.[[Construct]] to the definition specified in . + 1. Assert: _F_ is an ECMAScript function object or a built-in function object. + 1. If _F_ is an ECMAScript function object, then + 1. Assert: IsConstructor(_F_) is *false*. + 1. Assert: _F_ is an extensible object that does not have a *"prototype"* own property. + 1. Set _F_.[[Construct]] to the definition specified in . 1. Set _F_.[[ConstructorKind]] to ~base~. 1. If _writablePrototype_ is not present, set _writablePrototype_ to *true*. 1. If _prototype_ is not present, then @@ -21150,22 +21154,19 @@

Runtime Semantics: ClassDefinitionEvaluation

1. Let _proto_ be ! OrdinaryObjectCreate(_protoParent_). 1. If |ClassBody_opt| is not present, let _constructor_ be ~empty~. 1. Else, let _constructor_ be ConstructorMethod of |ClassBody|. - 1. If _constructor_ is ~empty~, then - 1. If |ClassHeritage_opt| is present, then - 1. Set _constructor_ to the result of parsing the source text -
constructor(...args) { super(...args); }
- using the syntactic grammar with the goal symbol |MethodDefinition[~Yield, ~Await]|. - 1. Else, - 1. Set _constructor_ to the result of parsing the source text -
constructor() {}
- using the syntactic grammar with the goal symbol |MethodDefinition[~Yield, ~Await]|. 1. Set the running execution context's LexicalEnvironment to _classScope_. - 1. Let _constructorInfo_ be ! DefineMethod of _constructor_ with arguments _proto_ and _constructorParent_. - 1. Let _F_ be _constructorInfo_.[[Closure]]. + 1. If _constructor_ is ~empty~, then + 1. Let _steps_ be the algorithm steps defined in . + 1. Let _F_ be ! CreateBuiltinFunction(_steps_, « [[ConstructorKind]], [[HomeObject]], [[SourceText]] », ~empty~, _constructorParent_, *true*). + 1. Perform ! SetFunctionLength(_F_, *+0*𝔽). + 1. Set _F_.[[HomeObject]] to _proto_. + 1. Else, + 1. Let _constructorInfo_ be ! DefineMethod of _constructor_ with arguments _proto_ and _constructorParent_. + 1. Let _F_ be _constructorInfo_.[[Closure]]. + 1. Perform MakeClassConstructor(_F_). 1. Perform SetFunctionName(_F_, _className_). 1. Perform MakeConstructor(_F_, *false*, _proto_). 1. If |ClassHeritage_opt| is present, set _F_.[[ConstructorKind]] to ~derived~. - 1. Perform MakeClassConstructor(_F_). 1. Perform CreateMethodProperty(_proto_, *"constructor"*, _F_). 1. If |ClassBody_opt| is not present, let _methods_ be a new empty List. 1. Else, let _methods_ be NonConstructorMethodDefinitions of |ClassBody|. @@ -21182,6 +21183,23 @@

Runtime Semantics: ClassDefinitionEvaluation

1. Perform _classScope_.InitializeBinding(_classBinding_, _F_). 1. Return _F_.
+ + +

Default Constructor Functions

+

When a Default Constructor Function is called with zero or more arguments which form the rest parameter ..._args_, the following steps are taken:

+ + 1. If NewTarget is *undefined*, throw a *TypeError* exception. + 1. Let _F_ be the active function object. + 1. If _F_.[[ConstructorKind]] is ~derived~, then + 1. NOTE: This branch behaves similarly to `constructor(...args) { super(...args); }`. The most notable distinction is that while the aforementioned ECMAScript source text observably calls `%Array.prototype[@@iterator]%`, this abstract operation does not. + 1. Let _func_ be ? _F_.[[GetPrototypeOf]](). + 1. If IsConstructor(_func_) is *false*, throw a *TypeError* exception. + 1. Return ? Construct(_func_, _args_, NewTarget). + 1. Else, + 1. NOTE: This branch behaves similarly to `constructor() {}`. + 1. Return ? OrdinaryCreateFromConstructor(NewTarget, `"%Object.prototype%"`). + +
@@ -26279,7 +26297,10 @@

Function.prototype.toString ( )

When the `toString` method is called, the following steps are taken:

1. Let _func_ be the *this* value. - 1. If _func_ is a built-in function object, return an implementation-defined String source code representation of _func_. The representation must have the syntax of a |NativeFunction|. Additionally, if _func_ has an [[InitialName]] internal slot and _func_.[[InitialName]] is a String, the portion of the returned String that would be matched by |NativeFunctionAccessor?| |PropertyName| must be the value of _func_.[[InitialName]]. + 1. If _func_ is a built-in function object, then + 1. If _func_ has a [[SourceText]] internal slot and _func_.[[SourceText]] is a sequence of Unicode code points, then + 1. Return ! CodePointsToString(_func_.[[SourceText]]). + 1. Return an implementation-defined String source code representation of _func_. The representation must have the syntax of a |NativeFunction|. Additionally, if _func_ has an [[InitialName]] internal slot and _func_.[[InitialName]] is a String, the portion of the returned String that would be matched by |NativeFunctionAccessor?| |PropertyName| must be the value of _func_.[[InitialName]]. 1. If Type(_func_) is Object and _func_ has a [[SourceText]] internal slot and _func_.[[SourceText]] is a sequence of Unicode code points and ! HostHasSourceTextAvailable(_func_) is *true*, then 1. Return ! CodePointsToString(_func_.[[SourceText]]). 1. If Type(_func_) is Object and IsCallable(_func_) is *true*, return an implementation-defined String source code representation of _func_. The representation must have the syntax of a |NativeFunction|.