Stage 2 Draft / January 19, 2024

ECMAScript 'throw' expressions

Introduction

This proposal defines new syntax to throw exceptions from within an expression context.

See the proposal repository for background material and discussion.

1 Syntax-Directed Operations

In addition to those defined in this section, specialized syntax-directed operations are defined throughout this specification.

1.1 Function Name Inference

1.1.1 Static Semantics: IsFunctionDefinition

The syntax-directed operation IsFunctionDefinition takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be the ParenthesizedExpression that is covered by CoverParenthesizedExpressionAndArrowParameterList.
  2. Return IsFunctionDefinition of expr.
PrimaryExpression : this IdentifierReference Literal ArrayLiteral ObjectLiteral RegularExpressionLiteral TemplateLiteral MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier NewExpression : new NewExpression LeftHandSideExpression : CallExpression OptionalExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression LogicalANDExpression : LogicalANDExpression && BitwiseORExpression LogicalORExpression : LogicalORExpression || LogicalANDExpression CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression AssignmentExpression : YieldExpression LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression CommaExpression : CommaExpression , AssignmentExpression ThrowExpression : throw Expression Expression : Expression , AssignmentExpression CommaExpression ThrowExpression
  1. Return false.
AssignmentExpression : ArrowFunction AsyncArrowFunction FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody } ClassExpression : class BindingIdentifieropt ClassTail
  1. Return true.

1.2 Miscellaneous

These operations are used in multiple places throughout the specification.

1.2.1 Static Semantics: AssignmentTargetType

The syntax-directed operation AssignmentTargetType takes no arguments and returns simple or invalid. It is defined piecewise over the following productions:

IdentifierReference : Identifier
  1. If this IdentifierReference is contained in strict mode code and StringValue of Identifier is either "eval" or "arguments", return invalid.
  2. Return simple.
IdentifierReference : yield await CallExpression : CallExpression [ Expression ] CallExpression . IdentifierName CallExpression . PrivateIdentifier MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName SuperProperty MemberExpression . PrivateIdentifier
  1. Return simple.
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be the ParenthesizedExpression that is covered by CoverParenthesizedExpressionAndArrowParameterList.
  2. Return AssignmentTargetType of expr.
PrimaryExpression : this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral CallExpression : CoverCallExpressionAndAsyncArrowHead SuperCall ImportCall CallExpression Arguments CallExpression TemplateLiteral NewExpression : new NewExpression MemberExpression : MemberExpression TemplateLiteral new MemberExpression Arguments NewTarget : new . target ImportMeta : import . meta LeftHandSideExpression : OptionalExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression LogicalANDExpression : LogicalANDExpression && BitwiseORExpression LogicalORExpression : LogicalORExpression || LogicalANDExpression CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression AssignmentExpression : YieldExpression ArrowFunction AsyncArrowFunction LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression CommaExpression : CommaExpression , AssignmentExpression ThrowExpression : throw Expression Expression : Expression , AssignmentExpression CommaExpression ThrowExpression
  1. Return invalid.

2 ECMAScript Language: Expressions

2.1 Comma Operator ( , )

Syntax

Expression[In, Yield, Await] : AssignmentExpression[?In, ?Yield, ?Await] Expression[?In, ?Yield, ?Await] , AssignmentExpression[?In, ?Yield, ?Await] CommaExpression[?In, ?Yield, ?Await] CommaExpression[In, Yield, Await] : AssignmentExpression[?In, ?Yield, ?Await] CommaExpression[?In, ?Yield, ?Await] , AssignmentExpression[?In, ?Yield, ?Await]

2.1.1 Runtime Semantics: Evaluation

Expression : Expression , AssignmentExpression CommaExpression : CommaExpression , AssignmentExpression
  1. Let lref be ? Evaluation of ExpressionCommaExpression.
  2. Perform ? GetValue(lref).
  3. Let rref be ? Evaluation of AssignmentExpression.
  4. Return ? GetValue(rref).
Note

GetValue must be called even though its value is not used because it may have observable side-effects.

2.2 The throw Operator

Syntax

Expression[In, Yield, Await] : ThrowExpression[?In, ?Yield, ?Await] ThrowExpression[In, Yield, Await] : throw Expression[?In, ?Yield, ?Await]

2.2.1 Runtime Semantics: Evaluation

ThrowExpression : throw Expression
  1. Let exprRef be ? Evaluation of Expression.
  2. Let exprValue be ? GetValue(exprRef).
  3. Return ThrowCompletion(exprValue).

3 ECMAScript Language: Statements and Declarations

3.1 Expression Statement

Syntax

ExpressionStatement[Yield, Await] : [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }] Expression[+In, ?Yield, ?Await] ; [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [, throw }] Expression[+In, ?Yield, ?Await] ; Note

An ExpressionStatement cannot start with a U+007B (LEFT CURLY BRACKET) because that might make it ambiguous with a Block. An ExpressionStatement cannot start with the function or class keywords because that would make it ambiguous with a FunctionDeclaration, a GeneratorDeclaration, or a ClassDeclaration. An ExpressionStatement cannot start with async function because that would make it ambiguous with an AsyncFunctionDeclaration. An ExpressionStatement cannot start with the two token sequence let [ because that would make it ambiguous with a let LexicalDeclaration whose first LexicalBinding was an ArrayBindingPattern. An ExpressionStatement cannot start with throw because that would make it ambiguous with a ThrowStatement.

4 ECMAScript Language: Functions and Classes

Note

Various ECMAScript language elements cause the creation of ECMAScript function objects (10.2). Evaluation of such functions starts with the execution of their [[Call]] internal method (10.2.1).

4.1 Tail Position Calls

4.1.1 Static Semantics: HasCallInTailPosition

The syntax-directed operation HasCallInTailPosition takes argument call (a CallExpression Parse Node, a MemberExpression Parse Node, or an OptionalChain Parse Node) and returns a Boolean.

Note 1

call is a Parse Node that represents a specific range of source text. When the following algorithms compare call to another Parse Node, it is a test of whether they represent the same source text.

Note 2

A potential tail position call that is immediately followed by return GetValue of the call result is also a possible tail position call. A function call cannot return a Reference Record, so such a GetValue operation will always return the same value as the actual function call result.

It is defined piecewise over the following productions:

StatementList : StatementList StatementListItem
  1. Let has be HasCallInTailPosition of StatementList with argument call.
  2. If has is true, return true.
  3. Return HasCallInTailPosition of StatementListItem with argument call.
FunctionStatementList : [empty] StatementListItem : Declaration Statement : VariableStatement EmptyStatement ExpressionStatement ContinueStatement BreakStatement ThrowStatement DebuggerStatement Block : { } ReturnStatement : return ; LabelledItem : FunctionDeclaration ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement CaseBlock : { }
  1. Return false.
IfStatement : if ( Expression ) Statement else Statement
  1. Let has be HasCallInTailPosition of the first Statement with argument call.
  2. If has is true, return true.
  3. Return HasCallInTailPosition of the second Statement with argument call.
IfStatement : if ( Expression ) Statement DoWhileStatement : do Statement while ( Expression ) ; WhileStatement : while ( Expression ) Statement ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement WithStatement : with ( Expression ) Statement
  1. Return HasCallInTailPosition of Statement with argument call.
LabelledStatement : LabelIdentifier : LabelledItem
  1. Return HasCallInTailPosition of LabelledItem with argument call.
ReturnStatement : return Expression ;
  1. Return HasCallInTailPosition of Expression with argument call.
SwitchStatement : switch ( Expression ) CaseBlock
  1. Return HasCallInTailPosition of CaseBlock with argument call.
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. Let has be false.
  2. If the first CaseClauses is present, let has be HasCallInTailPosition of the first CaseClauses with argument call.
  3. If has is true, return true.
  4. Let has be HasCallInTailPosition of DefaultClause with argument call.
  5. If has is true, return true.
  6. If the second CaseClauses is present, let has be HasCallInTailPosition of the second CaseClauses with argument call.
  7. Return has.
CaseClauses : CaseClauses CaseClause
  1. Let has be HasCallInTailPosition of CaseClauses with argument call.
  2. If has is true, return true.
  3. Return HasCallInTailPosition of CaseClause with argument call.
CaseClause : case Expression : StatementListopt DefaultClause : default : StatementListopt
  1. If StatementList is present, return HasCallInTailPosition of StatementList with argument call.
  2. Return false.
TryStatement : try Block Catch
  1. Return HasCallInTailPosition of Catch with argument call.
TryStatement : try Block Finally try Block Catch Finally
  1. Return HasCallInTailPosition of Finally with argument call.
Catch : catch ( CatchParameter ) Block
  1. Return HasCallInTailPosition of Block with argument call.
AssignmentExpression : YieldExpression ArrowFunction AsyncArrowFunction LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression CallExpression : SuperCall CallExpression [ Expression ] CallExpression . IdentifierName CallExpression . PrivateIdentifier NewExpression : new NewExpression MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier PrimaryExpression : this IdentifierReference Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral ThrowExpression : throw Expression
  1. Return false.
Expression : AssignmentExpression Expression , AssignmentExpression CommaExpression : AssignmentExpression CommaExpression , AssignmentExpression
  1. Return HasCallInTailPosition of AssignmentExpression with argument call.
ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
  1. Let has be HasCallInTailPosition of the first AssignmentExpression with argument call.
  2. If has is true, return true.
  3. Return HasCallInTailPosition of the second AssignmentExpression with argument call.
LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
  1. Return HasCallInTailPosition of BitwiseORExpression with argument call.
LogicalORExpression : LogicalORExpression || LogicalANDExpression
  1. Return HasCallInTailPosition of LogicalANDExpression with argument call.
CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression
  1. Return HasCallInTailPosition of BitwiseORExpression with argument call.
CallExpression : CoverCallExpressionAndAsyncArrowHead CallExpression Arguments CallExpression TemplateLiteral
  1. If this CallExpression is call, return true.
  2. Return false.
OptionalExpression : MemberExpression OptionalChain CallExpression OptionalChain OptionalExpression OptionalChain
  1. Return HasCallInTailPosition of OptionalChain with argument call.
OptionalChain : ?. [ Expression ] ?. IdentifierName ?. PrivateIdentifier OptionalChain [ Expression ] OptionalChain . IdentifierName OptionalChain . PrivateIdentifier
  1. Return false.
OptionalChain : ?. Arguments OptionalChain Arguments
  1. If this OptionalChain is call, return true.
  2. Return false.
MemberExpression : MemberExpression TemplateLiteral
  1. If this MemberExpression is call, return true.
  2. Return false.
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be the ParenthesizedExpression that is covered by CoverParenthesizedExpressionAndArrowParameterList.
  2. Return HasCallInTailPosition of expr with argument call.
ParenthesizedExpression : ( Expression )
  1. Return HasCallInTailPosition of Expression with argument call.

A Copyright & Software License

Copyright Notice

© 2024 Ron Buckton, Ecma International

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.