Stage 1 Draft / December 2, 2019

Function implementation hiding

Introduction

Background explanatory material for this specification can be found in the domenic/proposal-function-implementation-hiding repository. See also the open issues.

1Directive Prologues and the Use Strict Directive

A Directive Prologue is the longest sequence of ExpressionStatements occurring as the initial StatementListItems or ModuleItems of a FunctionBody, a ScriptBody, a ClassBody, or a ModuleBody and where each ExpressionStatement in the sequence consists entirely of a StringLiteral token followed by a semicolon. The semicolon may appear explicitly or may be inserted by automatic semicolon insertion. A Directive Prologue may be an empty sequence.

A Use Strict Directive is an ExpressionStatement in a Directive Prologue whose StringLiteral is either the exact code unit sequences "use strict" or 'use strict'. A Use Strict Directive may not contain an EscapeSequence or LineContinuation.

A Hide Implementation Directive is an ExpressionStatement in a Directive Prologue whose StringLiteral is either the exact code unit sequences "hide implementation" or 'hide implementation'. A Hide Implementation Directive may not contain an EscapeSequence or LineContinuation.

A Directive Prologue may contain more than one Use Strict Directiveof a given type of directive. However, an implementation may issue a warning if this occurs.

Note

The ExpressionStatements of a Directive Prologue are evaluated normally during evaluation of the containing production. Implementations may define implementation specific meanings for ExpressionStatements which are not a Use Strict Directiveone of the above-defined directives and which occur in a Directive Prologue. If an appropriate notification mechanism exists, an implementation should issue a warning if it encounters in a Directive Prologue an ExpressionStatement that is not a Use Strict Directiveone of the above-defined directives and which does not have a meaning defined by the implementation.

2Function Implementation Hidden Code

The output of Function.prototype.toString ( ) and of any runtime mechanisms for inspecting an Error object's stack trace omits information about the function's implementation when the function was created inside function implementation hidden code. Code is interpreted as function implementation hidden code in the following situations:

3Runtime Semantics: InstantiateFunctionObject

With parameter scope.

FunctionDeclaration:functionBindingIdentifier(FormalParameters){FunctionBody}
  1. If the function code for FunctionDeclaration is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let name be StringValue of BindingIdentifier.
  3. Let F be FunctionCreate(Normal, FormalParameters, FunctionBody, scope, strict).
  4. Perform MakeConstructor(F).
  5. Perform SetFunctionName(F, name).
  6. If the code matched by this FunctionDeclaration is not function implementation hidden code, set F.[[SourceText]] to the source text matched by FunctionDeclaration.
  7. Return F.
FunctionDeclaration:function(FormalParameters){FunctionBody}
  1. If the function code for FunctionDeclaration is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let F be FunctionCreate(Normal, FormalParameters, FunctionBody, scope, strict).
  3. Perform MakeConstructor(F).
  4. Perform SetFunctionName(F, "default").
  5. If the code matched by this FunctionDeclaration is not function implementation hidden code, set F.[[SourceText]] to the source text matched by FunctionDeclaration.
  6. Return F.
Note

An anonymous FunctionDeclaration can only occur as part of an export default declaration.

4Runtime Semantics: Evaluation

FunctionDeclaration:functionBindingIdentifier(FormalParameters){FunctionBody}
  1. Return NormalCompletion(empty).
Note 1

An alternative semantics is provided in B.3.3.

FunctionDeclaration:function(FormalParameters){FunctionBody}
  1. Return NormalCompletion(empty).
FunctionExpression:function(FormalParameters){FunctionBody}
  1. If the function code for FunctionExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let closure be FunctionCreate(Normal, FormalParameters, FunctionBody, scope, strict).
  4. Perform MakeConstructor(closure).
  5. If the code matched by this FunctionExpression is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by FunctionExpression.
  6. Return closure.
FunctionExpression:functionBindingIdentifier(FormalParameters){FunctionBody}
  1. If the function code for FunctionExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the running execution context's LexicalEnvironment.
  3. Let funcEnv be NewDeclarativeEnvironment(scope).
  4. Let envRec be funcEnv's EnvironmentRecord.
  5. Let name be StringValue of BindingIdentifier.
  6. Perform envRec.CreateImmutableBinding(name, false).
  7. Let closure be FunctionCreate(Normal, FormalParameters, FunctionBody, funcEnv, strict).
  8. Perform MakeConstructor(closure).
  9. Perform SetFunctionName(closure, name).
  10. If the code matched by this FunctionExpression is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by FunctionExpression.
  11. Perform envRec.InitializeBinding(name, closure).
  12. Return closure.
Note 2

The BindingIdentifier in a FunctionExpression can be referenced from inside the FunctionExpression's FunctionBody to allow the function to call itself recursively. However, unlike in a FunctionDeclaration, the BindingIdentifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression.

Note 3

A prototype property is automatically created for every function defined using a FunctionDeclaration or FunctionExpression, to allow for the possibility that the function will be used as a constructor.

FunctionStatementList:[empty]
  1. Return NormalCompletion(undefined).

5Runtime Semantics: Evaluation

ArrowFunction:ArrowParameters=>ConciseBody
  1. If the function code for this ArrowFunction is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let parameters be CoveredFormalsList of ArrowParameters.
  4. Let closure be FunctionCreate(Arrow, parameters, ConciseBody, scope, strict).
  5. If the code matched by this ArrowFunction is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by ArrowFunction.
  6. Return closure.
Note

An ArrowFunction does not define local bindings for arguments, super, this, or new.target. Any reference to arguments, super, this, or new.target within an ArrowFunction must resolve to a binding in a lexically enclosing environment. Typically this will be the Function Environment of an immediately enclosing function. Even though an ArrowFunction may contain references to super, the function object created in step 4 is not made into a method by performing MakeMethod. An ArrowFunction that references super is always contained within a non-ArrowFunction and the necessary state to implement super is accessible via the scope that is captured by the function object of the ArrowFunction.

6Runtime Semantics: DefineMethod

With parameters object and optional parameter functionPrototype.

MethodDefinition:PropertyName(StrictFormalParameters){FunctionBody}
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. If the function code for this MethodDefinition is strict mode code, let strict be true. Otherwise let strict be false.
  4. Let scope be the running execution context's LexicalEnvironment.
  5. If functionPrototype was passed as a parameter, let kind be Normal; otherwise let kind be Method.
  6. Let closure be FunctionCreate(kind, StrictFormalParameters, FunctionBody, scope, strict). If functionPrototype was passed as a parameter, then pass its value as the prototype optional argument of FunctionCreate.
  7. Perform MakeMethod(closure, object).
  8. If the code matched by this MethodDefinition is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by MethodDefinition.
  9. Return the Record{[[Key]]: propKey, [[Closure]]: closure}.

7Runtime Semantics: PropertyDefinitionEvaluation

With parameters object and enumerable.

MethodDefinition:PropertyName(StrictFormalParameters){FunctionBody}
  1. Let methodDef be DefineMethod of MethodDefinition with argument object.
  2. ReturnIfAbrupt(methodDef).
  3. Perform SetFunctionName(methodDef.[[Closure]], methodDef.[[Key]]).
  4. Let desc be the PropertyDescriptor{[[Value]]: methodDef.[[Closure]], [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true}.
  5. Return ? DefinePropertyOrThrow(object, methodDef.[[Key]], desc).
MethodDefinition:GeneratorMethod

See 14.4.

MethodDefinition:getPropertyName(){FunctionBody}
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. If the function code for this MethodDefinition is strict mode code, let strict be true. Otherwise let strict be false.
  4. Let scope be the running execution context's LexicalEnvironment.
  5. Let formalParameterList be the production FormalParameters:[empty] .
  6. Let closure be FunctionCreate(Method, formalParameterList, FunctionBody, scope, strict).
  7. Perform MakeMethod(closure, object).
  8. Perform SetFunctionName(closure, propKey, "get").
  9. If the code matched by this MethodDefinition is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by MethodDefinition.
  10. Let desc be the PropertyDescriptor{[[Get]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true}.
  11. Return ? DefinePropertyOrThrow(object, propKey, desc).
MethodDefinition:setPropertyName(PropertySetParameterList){FunctionBody}
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. If the function code for this MethodDefinition is strict mode code, let strict be true. Otherwise let strict be false.
  4. Let scope be the running execution context's LexicalEnvironment.
  5. Let closure be FunctionCreate(Method, PropertySetParameterList, FunctionBody, scope, strict).
  6. Perform MakeMethod(closure, object).
  7. Perform SetFunctionName(closure, propKey, "set").
  8. If the code matched by this MethodDefinition is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by MethodDefinition.
  9. Let desc be the PropertyDescriptor{[[Set]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true}.
  10. Return ? DefinePropertyOrThrow(object, propKey, desc).

8Runtime Semantics: InstantiateFunctionObject

With parameter scope.

GeneratorDeclaration:function*BindingIdentifier(FormalParameters){GeneratorBody}
  1. If the function code for GeneratorDeclaration is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let name be StringValue of BindingIdentifier.
  3. Let F be GeneratorFunctionCreate(Normal, FormalParameters, GeneratorBody, scope, strict).
  4. Let prototype be ObjectCreate(%GeneratorPrototype%).
  5. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  6. Perform SetFunctionName(F, name).
  7. If the code matched by this GeneratorDeclaration is not function implementation hidden code, set F.[[SourceText]] to the source text matched by GeneratorDeclaration.
  8. Return F.
GeneratorDeclaration:function*(FormalParameters){GeneratorBody}
  1. If the function code for GeneratorDeclaration is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let F be GeneratorFunctionCreate(Normal, FormalParameters, GeneratorBody, scope, strict).
  3. Let prototype be ObjectCreate(%GeneratorPrototype%).
  4. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  5. Perform SetFunctionName(F, "default").
  6. If the code matched by this GeneratorDeclaration is not function implementation hidden code, set F.[[SourceText]] to the source text matched by GeneratorDeclaration.
  7. Return F.
Note

An anonymous GeneratorDeclaration can only occur as part of an export default declaration.

9Runtime Semantics: PropertyDefinitionEvaluation

With parameter object and enumerable.

GeneratorMethod:*PropertyName(StrictFormalParameters){GeneratorBody}
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. If the function code for this GeneratorMethod is strict mode code, let strict be true. Otherwise let strict be false.
  4. Let scope be the running execution context's LexicalEnvironment.
  5. Let closure be GeneratorFunctionCreate(Method, StrictFormalParameters, GeneratorBody, scope, strict).
  6. Perform MakeMethod(closure, object).
  7. Let prototype be ObjectCreate(%GeneratorPrototype%).
  8. Perform DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  9. Perform SetFunctionName(closure, propKey).
  10. If the code matched by this GeneratorMethod is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by GeneratorMethod.
  11. Let desc be the PropertyDescriptor{[[Value]]: closure, [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true}.
  12. Return ? DefinePropertyOrThrow(object, propKey, desc).

10Runtime Semantics: Evaluation

GeneratorExpression:function*(FormalParameters){GeneratorBody}
  1. If the function code for this GeneratorExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let closure be GeneratorFunctionCreate(Normal, FormalParameters, GeneratorBody, scope, strict).
  4. Let prototype be ObjectCreate(%GeneratorPrototype%).
  5. Perform DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  6. If the code matched by this GeneratorExpression is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by GeneratorExpression.
  7. Return closure.
GeneratorExpression:function*BindingIdentifier(FormalParameters){GeneratorBody}
  1. If the function code for this GeneratorExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the running execution context's LexicalEnvironment.
  3. Let funcEnv be NewDeclarativeEnvironment(scope).
  4. Let envRec be funcEnv's EnvironmentRecord.
  5. Let name be StringValue of BindingIdentifier.
  6. Perform envRec.CreateImmutableBinding(name, false).
  7. Let closure be GeneratorFunctionCreate(Normal, FormalParameters, GeneratorBody, funcEnv, strict).
  8. Let prototype be ObjectCreate(%GeneratorPrototype%).
  9. Perform DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  10. Perform SetFunctionName(closure, name).
  11. Perform envRec.InitializeBinding(name, closure).
  12. If the code matched by this GeneratorExpression is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by GeneratorExpression.
  13. Return closure.
Note

The BindingIdentifier in a GeneratorExpression can be referenced from inside the GeneratorExpression's FunctionBody to allow the generator code to call itself recursively. However, unlike in a GeneratorDeclaration, the BindingIdentifier in a GeneratorExpression cannot be referenced from and does not affect the scope enclosing the GeneratorExpression.

11Runtime Semantics: InstantiateFunctionObject

With parameter scope.

AsyncGeneratorDeclaration:async[no LineTerminator here]function*BindingIdentifier(FormalParameters){AsyncGeneratorBody}
  1. If the function code for AsyncGeneratorDeclaration is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let name be StringValue of BindingIdentifier.
  3. Let F be ! AsyncGeneratorFunctionCreate(Normal, FormalParameters, AsyncGeneratorBody, scope, strict).
  4. Let prototype be ! ObjectCreate(%AsyncGeneratorPrototype%).
  5. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  6. Perform ! SetFunctionName(F, name).
  7. If the code matched by this AsyncGeneratorDeclaration is not function implementation hidden code, set F.[[SourceText]] to the source text matched by AsyncGeneratorDeclaration.
  8. Return F.
AsyncGeneratorDeclaration:async[no LineTerminator here]function*(FormalParameters){AsyncGeneratorBody}
  1. If the function code for AsyncGeneratorDeclaration is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let F be AsyncGeneratorFunctionCreate(Normal, FormalParameters, AsyncGeneratorBody, scope, strict).
  3. Let prototype be ObjectCreate(%AsyncGeneratorPrototype%).
  4. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  5. Perform SetFunctionName(F, "default").
  6. If the code matched by this AsyncGeneratorDeclaration is not function implementation hidden code, set F.[[SourceText]] to the source text matched by AsyncGeneratorDeclaration.
  7. Return F.
Note

An anonymous AsyncGeneratorDeclaration can only occur as part of an export default declaration.

12Runtime Semantics: PropertyDefinitionEvaluation

With parameter object and enumerable.

AsyncGeneratorMethod:async[no LineTerminator here]*PropertyName(UniqueFormalParameters){AsyncGeneratorBody}
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. If the function code for this AsyncGeneratorMethod is strict mode code, let strict be true. Otherwise let strict be false.
  4. Let scope be the running execution context's LexicalEnvironment.
  5. Let closure be ! AsyncGeneratorFunctionCreate(Method, UniqueFormalParameters, AsyncGeneratorBody, scope, strict).
  6. Perform ! MakeMethod(closure, object).
  7. Let prototype be ! ObjectCreate(%AsyncGeneratorPrototype%).
  8. Perform ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  9. Perform ! SetFunctionName(closure, propKey).
  10. If the code matched by this AsyncGeneratorMethod is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by AsyncGeneratorMethod.
  11. Let desc be PropertyDescriptor{[[Value]]: closure, [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true}.
  12. Return ? DefinePropertyOrThrow(object, propKey, desc).

13Runtime Semantics: Evaluation

AsyncGeneratorExpression:async[no LineTerminator here]function*(FormalParameters){AsyncGeneratorBody}
  1. If the function code for this AsyncGeneratorExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let closure be ! AsyncGeneratorFunctionCreate(Normal, FormalParameters, AsyncGeneratorBody, scope, strict).
  4. Let prototype be ! ObjectCreate(%AsyncGeneratorPrototype%).
  5. Perform ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  6. If the code matched by this AsyncGeneratorExpression is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by AsyncGeneratorExpression.
  7. Return closure.
AsyncGeneratorExpression:async[no LineTerminator here]function*BindingIdentifier(FormalParameters){AsyncGeneratorBody}
  1. If the function code for this AsyncGeneratorExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the running execution context's LexicalEnvironment.
  3. Let funcEnv be ! NewDeclarativeEnvironment(scope).
  4. Let envRec be funcEnv's EnvironmentRecord.
  5. Let name be StringValue of BindingIdentifier.
  6. Perform ! envRec.CreateImmutableBinding(name).
  7. Let closure be ! AsyncGeneratorFunctionCreate(Normal, FormalParameters, AsyncGeneratorBody, funcEnv, strict).
  8. Let prototype be ! ObjectCreate(%AsyncGeneratorPrototype%).
  9. Perform ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  10. Perform ! SetFunctionName(closure, name).
  11. Perform ! envRec.InitializeBinding(name, closure).
  12. If the code matched by this AsyncGeneratorExpression is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by AsyncGeneratorExpression.
  13. Return closure.
Note

The BindingIdentifier in an AsyncGeneratorExpression can be referenced from inside the AsyncGeneratorExpression's AsyncGeneratorBody to allow the generator code to call itself recursively. However, unlike in an AsyncGeneratorDeclaration, the BindingIdentifier in an AsyncGeneratorExpression cannot be referenced from and does not affect the scope enclosing the AsyncGeneratorExpression.

14Runtime Semantics: BindingClassDeclarationEvaluation

ClassDeclaration:classBindingIdentifierClassTail
  1. Let className be StringValue of BindingIdentifier.
  2. Let value be the result of ClassDefinitionEvaluation of ClassTail with argument className.
  3. ReturnIfAbrupt(value).
  4. Let hasNameProperty be ? HasOwnProperty(value, "name").
  5. If hasNameProperty is false, perform SetFunctionName(value, className).
  6. If the code matched by this ClassDeclaration is not function implementation hidden code, set value.[[SourceText]] to the source text matched by ClassDeclaration.
  7. Let env be the running execution context's LexicalEnvironment.
  8. Perform ? InitializeBoundName(className, value, env).
  9. Return value.
ClassDeclaration:classClassTail
  1. Let value be the result of ClassDefinitionEvaluation of ClassTail with argument undefined.
  2. If the code matched by this ClassDeclaration is not function implementation hidden code, set value.[[SourceText]] to the source text matched by ClassDeclaration.
  3. Return value.
Note

ClassDeclaration:classClassTail only occurs as part of an ExportDeclaration and the setting of a name property and establishing its binding are handled as part of the evaluation action for that production. See 15.2.3.9.

15Runtime Semantics: Evaluation

ClassDeclaration:classBindingIdentifierClassTail
  1. Let status be the result of BindingClassDeclarationEvaluation of this ClassDeclaration.
  2. ReturnIfAbrupt(status).
  3. Return NormalCompletion(empty).
Note 1

ClassDeclaration:classClassTail only occurs as part of an ExportDeclaration and is never directly evaluated.

ClassExpression:classBindingIdentifieroptClassTail
  1. If BindingIdentifieropt is not present, let className be undefined.
  2. Else, let className be StringValue of BindingIdentifier.
  3. Let value be the result of ClassDefinitionEvaluation of ClassTail with argument className.
  4. ReturnIfAbrupt(value).
  5. If className is not undefined, then
    1. Let hasNameProperty be ? HasOwnProperty(value, "name").
    2. If hasNameProperty is false, then
      1. Perform SetFunctionName(value, className).
  6. If the code matched by this ClassExpression is not function implementation hidden code, set value.[[SourceText]] to the source text matched by ClassExpression.
  7. Return NormalCompletion(value).
Note 2

If the class definition included a name static method then that method is not over-written with a name data property for the class name.

16Runtime Semantics: InstantiateFunctionObject

With parameter scope.

AsyncFunctionDeclaration:async[no LineTerminator here]functionBindingIdentifier(FormalParameters){AsyncFunctionBody}
  1. If the function code for AsyncFunctionDeclaration is strict mode code, let strict be true. Otherwise, let strict be false.
  2. Let name be StringValue of BindingIdentifier.
  3. Let F be ! AsyncFunctionCreate(Normal, FormalParameters, AsyncFunctionBody, scope, strict).
  4. Perform ! SetFunctionName(F, name).
  5. If the code matched by this AsyncFunctionDeclaration is not function implementation hidden code, set F.[[SourceText]] to the source text matched by AsyncFunctionDeclaration.
  6. Return F.
AsyncFunctionDeclaration:async[no LineTerminator here]function(FormalParameters){AsyncFunctionBody}
  1. If the function code for AsyncFunctionDeclaration is strict mode code, let strict be true. Otherwise, let strict be false.
  2. Let F be ! AsyncFunctionCreate(Normal, FormalParameters, AsyncFunctionBody, scope, strict).
  3. Perform ! SetFunctionName(F, "default").
  4. If the code matched by this AsyncFunctionDeclaration is not function implementation hidden code, set F.[[SourceText]] to the source text matched by AsyncFunctionDeclaration.
  5. Return F.

17Runtime Semantics: PropertyDefinitionEvaluation

With parameters object and enumerable.

AsyncMethod:async[no LineTerminator here]PropertyName(UniqueFormalParameters){AsyncFunctionBody}
  1. Let propKey be the result of evaluating PropertyName.
  2. ReturnIfAbrupt(propKey).
  3. If the function code for this AsyncMethod is strict mode code, let strict be true. Otherwise let strict be false.
  4. Let scope be the LexicalEnvironment of the running execution context.
  5. Let closure be ! AsyncFunctionCreate(Method, UniqueFormalParameters, AsyncFunctionBody, scope, strict).
  6. Perform ! MakeMethod(closure, object).
  7. Perform ! SetFunctionName(closure, propKey).
  8. If the code matched by this AsyncMethod is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by AsyncMethod.
  9. Let desc be the PropertyDescriptor{[[Value]]: closure, [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true}.
  10. Return ? DefinePropertyOrThrow(object, propKey, desc).

18Runtime Semantics: Evaluation

AsyncFunctionDeclaration:async[no LineTerminator here]functionBindingIdentifier(FormalParameters){AsyncFunctionBody}
  1. Return NormalCompletion(empty).
AsyncFunctionDeclaration:async[no LineTerminator here]function(FormalParameters){AsyncFunctionBody}
  1. Return NormalCompletion(empty).
AsyncFunctionExpression:async[no LineTerminator here]function(FormalParameters){AsyncFunctionBody}
  1. If the function code for AsyncFunctionExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let closure be ! AsyncFunctionCreate(Normal, FormalParameters, AsyncFunctionBody, scope, strict).
  4. If the code matched by this AsyncFunctionExpression is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by AsyncFunctionExpression.
  5. Return closure.
AsyncFunctionExpression:async[no LineTerminator here]functionBindingIdentifier(FormalParameters){AsyncFunctionBody}
  1. If the function code for AsyncFunctionExpression is strict mode code, let strict be true. Otherwise let strict be false.
  2. Let scope be the LexicalEnvironment of the running execution context.
  3. Let funcEnv be ! NewDeclarativeEnvironment(scope).
  4. Let envRec be funcEnv's EnvironmentRecord.
  5. Let name be StringValue of BindingIdentifier.
  6. Perform ! envRec.CreateImmutableBinding(name).
  7. Let closure be ! AsyncFunctionCreate(Normal, FormalParameters, AsyncFunctionBody, funcEnv, strict).
  8. Perform ! SetFunctionName(closure, name).
  9. Perform ! envRec.InitializeBinding(name, closure).
  10. If the code matched by this AsyncFunctionExpression is not function implementation hidden code, set closure.[[SourceText]] to the source text matched by AsyncFunctionExpression.
  11. Return closure.
AwaitExpression:awaitUnaryExpression
  1. Let exprRef be the result of evaluating UnaryExpression.
  2. Let value be ? GetValue(exprRef).
  3. Return ? Await(value).

19Runtime Semantics: CreateDynamicFunction( constructor, newTarget, kind, args )

The abstract operation CreateDynamicFunction is called with arguments constructor, newTarget, kind, and args. constructor is the constructor function that is performing this action, newTarget is the constructor that new was initially applied to, kind is either "normal", "generator", or "async", and args is a List containing the actual argument values that were passed to constructor. The following steps are taken:

  1. Assert: The execution context stack has at least two elements.
  2. Let callerContext be the second to top element of the execution context stack.
  3. Let callerRealm be callerContext's Realm.
  4. Let calleeRealm be the current Realm Record.
  5. Perform ? HostEnsureCanCompileStrings(callerRealm, calleeRealm).
  6. If newTarget is undefined, let newTarget be constructor.
  7. If kind is "normal", then
    1. Let goal be the grammar symbol FunctionBody[~Yield, ~Await].
    2. Let parameterGoal be the grammar symbol FormalParameters[~Yield, ~Await].
    3. Let fallbackProto be "%FunctionPrototype%".
  8. Else if kind is "generator", then
    1. Let goal be the grammar symbol GeneratorBody.
    2. Let parameterGoal be the grammar symbol FormalParameters[+Yield, ~Await].
    3. Let fallbackProto be "%Generator%".
  9. Else,
    1. Assert: kind is "async".
    2. Let goal be the grammar symbol AsyncFunctionBody.
    3. Let parameterGoal be the grammar symbol FormalParameters[~Yield, +Await].
    4. Let fallbackProto be "%AsyncFunctionPrototype%".
  10. Let argCount be the number of elements in args.
  11. Let P be the empty String.
  12. If argCount = 0, let bodyText be the empty String.
  13. Else if argCount = 1, let bodyText be args[0].
  14. Else argCount > 1,
    1. Let firstArg be args[0].
    2. Let P be ? ToString(firstArg).
    3. Let k be 1.
    4. Repeat, while k < argCount-1
      1. Let nextArg be args[k].
      2. Let nextArgString be ? ToString(nextArg).
      3. Let P be the result of concatenating the previous value of P, the String "," (a comma), and nextArgString.
      4. Increase k by 1.
    5. Let bodyText be args[k].
  15. Let bodyText be ? ToString(bodyText).
  16. Let parameters be the result of parsing P, interpreted as UTF-16 encoded Unicode text as described in 6.1.4, using parameterGoal as the goal symbol. Throw a SyntaxError exception if the parse fails.
  17. Let body be the result of parsing bodyText, interpreted as UTF-16 encoded Unicode text as described in 6.1.4, using goal as the goal symbol. Throw a SyntaxError exception if the parse fails.
  18. If bodyText is strict mode code, then let strict be true, else let strict be false.
  19. If bodyText is function implementation hidden code, then let noSourceText be true, else let noSourceText be false.
  20. If any static semantics errors are detected for parameters or body, throw a SyntaxError or a ReferenceError exception, depending on the type of the error. If strict is true, the Early Error rules for UniqueFormalParameters:FormalParameters are applied. Parsing and early error detection may be interweaved in an implementation dependent manner.
  21. If ContainsUseStrict of body is true and IsSimpleParameterList of parameters is false, throw a SyntaxError exception.
  22. If any element of the BoundNames of parameters also occurs in the LexicallyDeclaredNames of body, throw a SyntaxError exception.
  23. If body Contains SuperCall is true, throw a SyntaxError exception.
  24. If parameters Contains SuperCall is true, throw a SyntaxError exception.
  25. If body Contains SuperProperty is true, throw a SyntaxError exception.
  26. If parameters Contains SuperProperty is true, throw a SyntaxError exception.
  27. If kind is "generator", then
    1. If parameters Contains YieldExpression is true, throw a SyntaxError exception.
  28. If kind is "async", then
    1. If parameters Contains AwaitExpression is true, throw a SyntaxError exception.
  29. If strict is true, then
    1. If BoundNames of parameters contains any duplicate elements, throw a SyntaxError exception.
  30. Let proto be ? GetPrototypeFromConstructor(newTarget, fallbackProto).
  31. Let F be FunctionAllocate(proto, strict, kind).
  32. Let realmF be F.[[Realm]].
  33. Let scope be realmF.[[GlobalEnv]].
  34. Perform FunctionInitialize(F, Normal, parameters, body, scope).
  35. If kind is "generator", then
    1. Let prototype be ObjectCreate(%GeneratorPrototype%).
    2. Perform DefinePropertyOrThrow(F, "prototype", PropertyDescriptor{[[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}).
  36. Else if kind is "normal", perform MakeConstructor(F).
  37. NOTE: Async functions are not constructable and do not have a [[Construct]] internal method or a "prototype" property.
  38. Perform SetFunctionName(F, "anonymous").
  39. Let prefix be the prefix associated with kind in Table 1.
  40. Let sourceText be the String value whose elements are, in order, the code units of prefix, the code units of " anonymous(", the code units of P, 0x000A (LINE FEED), the code units of ") {", 0x000A (LINE FEED), the code units of bodyText, 0x000A (LINE FEED), and the code units of "}".
  41. If noSourceText is false, set F.[[SourceText]] to sourceText.
  42. Return F.
Note

A prototype property is automatically created for every function created using CreateDynamicFunction, to provide for the possibility that the function will be used as a constructor.

Table 1: Dynamic Function SourceText Prefixes
KindPrefix
"normal""function"
"generator""function*"
"async""async function"
"async generator""async function*"

20Forbidden Extensions

Add the following bullet point: