The binary AST is isomorphic to ECMA-262 Syntactic Grammar. That is, an instance of a production of the binary AST grammar, or a binary AST Node, corresponds to some Parse Node in the ECMA-262 syntactic grammar. This document specifies the following things.
A compliant binary AST Encoder, for a source text that matches either the
The inverse of
This section is derived from Shift AST Spec and parts are Copyright 2014-2017 Shape Security, Inc.
Unlike the Shift AST spec, interface types are not used to inherit fields to control over ordering of fields. Type hierarchies that are not used to discriminate are collapsed to make space costs simple. Nor are they used to discriminate types, for which explicitly discriminated unions types are used.
The grammar is presented in WebIDL with the [TypeIndicator]
and [NonEmpty]
extensions per Shift AST spec. The [Lazy]
extension serves as a hint to the surface encoding that the [Lazy]
attribute should be skippable in the byte stream in constant time. The typedefs
of or
types are to be read as recursive sum types. In text below, the "is a Foo
" prose is shorthand for checking the node's type
attribute being equal to "Foo"
.
// Type aliases and enums.
typedef FrozenArray<(SpreadElement or Expression)> Arguments;
typedef DOMString string;
// Identifier:: IdentifierName but not ReservedWord
typedef string Identifier;
typedef string IdentifierName;
typedef string Label;
enum VariableDeclarationKind {
"var",
"let",
"const"
};
enum CompoundAssignmentOperator {
"+=",
"-=",
"*=",
"/=",
"%=",
"**=",
"<<=",
">>=",
">>>=",
"|=",
"^=",
"&="
};
enum BinaryOperator {
",",
"||",
"&&",
"|",
"^",
"&",
"==",
"!=",
"===",
"!==",
"<",
"<=",
">",
">=",
"in",
"instanceof",
"<<",
">>",
">>>",
"+",
"-",
"*",
"/",
"%",
"**",
};
enum UnaryOperator {
"+",
"-",
"!",
"~",
"typeof",
"void",
"delete"
};
enum UpdateOperator {
"++",
"--"
};
enum AssertedDeclaredKind {
"var",
"non-const lexical",
"const lexical"
};
// deferred assertions
interface AssertedDeclaredName {
attribute IdentifierName name;
attribute AssertedDeclaredKind kind;
attribute boolean isCaptured;
};
interface AssertedPositionalParameterName {
attribute unsigned long index;
attribute IdentifierName name;
attribute boolean isCaptured;
};
interface AssertedRestParameterName {
attribute IdentifierName name;
attribute boolean isCaptured;
};
interface AssertedParameterName {
attribute IdentifierName name;
attribute boolean isCaptured;
};
typedef (AssertedPositionalParameterName or
AssertedRestParameterName or
AssertedParameterName)
AssertedMaybePositionalParameterName;
interface AssertedBoundName {
attribute IdentifierName name;
attribute boolean isCaptured;
};
interface AssertedBlockScope {
attribute FrozenArray<AssertedDeclaredName> declaredNames;
attribute boolean hasDirectEval;
};
interface AssertedScriptGlobalScope {
attribute FrozenArray<AssertedDeclaredName> declaredNames;
attribute boolean hasDirectEval;
};
interface AssertedVarScope {
attribute FrozenArray<AssertedDeclaredName> declaredNames;
attribute boolean hasDirectEval;
};
interface AssertedParameterScope {
attribute FrozenArray<AssertedMaybePositionalParameterName> paramNames;
attribute boolean hasDirectEval;
attribute boolean isSimpleParameterList;
};
interface AssertedBoundNamesScope {
attribute FrozenArray<AssertedBoundName> boundNames;
attribute boolean hasDirectEval;
};
// nodes
interface Node {
[TypeIndicator] readonly attribute Type type;
};
typedef (Script or Module) Program;
typedef (DoWhileStatement or
ForInStatement or
ForOfStatement or
ForStatement or
WhileStatement)
IterationStatement;
typedef (Block or
BreakStatement or
ContinueStatement or
ClassDeclaration or
DebuggerStatement or
EmptyStatement or
ExpressionStatement or
FunctionDeclaration or
IfStatement or
IterationStatement or
LabelledStatement or
ReturnStatement or
SwitchStatement or
SwitchStatementWithDefault or
ThrowStatement or
TryCatchStatement or
TryFinallyStatement or
VariableDeclaration or
WithStatement)
Statement;
typedef (LiteralBooleanExpression or
LiteralInfinityExpression or
LiteralNullExpression or
LiteralNumericExpression or
LiteralStringExpression)
Literal;
typedef (Literal or
LiteralRegExpExpression or
ArrayExpression or
ArrowExpression or
AssignmentExpression or
BinaryExpression or
CallExpression or
CompoundAssignmentExpression or
ComputedMemberExpression or
ConditionalExpression or
ClassExpression or
FunctionExpression or
IdentifierExpression or
NewExpression or
NewTargetExpression or
ObjectExpression or
UnaryExpression or
StaticMemberExpression or
TemplateExpression or
ThisExpression or
UpdateExpression or
YieldExpression or
YieldStarExpression or
AwaitExpression)
Expression;
typedef (ComputedPropertyName or
LiteralPropertyName)
PropertyName;
typedef (Method or Getter or Setter) MethodDefinition;
typedef (MethodDefinition or
DataProperty or
ShorthandProperty)
ObjectProperty;
typedef (ExportAllFrom or
ExportFrom or
ExportLocals or
ExportDefault or
Export)
ExportDeclaration;
typedef (ImportNamespace or Import) ImportDeclaration;
typedef (EagerFunctionDeclaration or
LazyFunctionDeclaration) FunctionDeclaration;
typedef (EagerFunctionExpression or
LazyFunctionExpression) FunctionExpression;
typedef (EagerMethod or LazyMethod) Method;
typedef (EagerGetter or LazyGetter) Getter;
typedef (EagerSetter or LazySetter) Setter;
typedef (EagerArrowExpressionWithFunctionBody or
LazyArrowExpressionWithFunctionBody or
EagerArrowExpressionWithExpression or
LazyArrowExpressionWithExpression) ArrowExpression;
// bindings
interface BindingIdentifier : Node {
attribute Identifier name;
};
typedef (ObjectBinding or
ArrayBinding)
BindingPattern;
typedef (BindingPattern or
BindingIdentifier)
Binding;
typedef (AssignmentTargetIdentifier or
ComputedMemberAssignmentTarget or
StaticMemberAssignmentTarget)
SimpleAssignmentTarget;
typedef (ObjectAssignmentTarget or
ArrayAssignmentTarget)
AssignmentTargetPattern;
// `DestructuringAssignmentTarget`
typedef (AssignmentTargetPattern or
SimpleAssignmentTarget)
AssignmentTarget;
// `FormalParameter`
typedef (Binding or
BindingWithInitializer)
Parameter;
interface BindingWithInitializer : Node {
attribute Binding binding;
attribute Expression init;
};
interface AssignmentTargetIdentifier : Node {
attribute Identifier name;
};
interface ComputedMemberAssignmentTarget : Node {
// The object whose property is being assigned.
attribute (Expression or Super) _object;
// The expression resolving to the name of the property to be accessed.
attribute Expression expression;
};
interface StaticMemberAssignmentTarget : Node {
// The object whose property is being assigned.
attribute (Expression or Super) _object;
// The name of the property to be accessed.
attribute IdentifierName property;
};
// `ArrayBindingPattern`
interface ArrayBinding : Node {
// The elements of the array pattern; a null value represents an elision.
attribute FrozenArray<(Binding or BindingWithInitializer)?> elements;
attribute Binding? rest;
};
// `SingleNameBinding`
interface BindingPropertyIdentifier : Node {
attribute BindingIdentifier binding;
attribute Expression? init;
};
// `BindingProperty :: PropertyName : BindingElement`
interface BindingPropertyProperty : Node {
attribute PropertyName name;
attribute (Binding or BindingWithInitializer) binding;
};
typedef (BindingPropertyIdentifier or
BindingPropertyProperty)
BindingProperty;
interface ObjectBinding : Node {
attribute FrozenArray<BindingProperty> properties;
};
// This interface represents the case where the initializer is present in
// `AssignmentElement :: DestructuringAssignmentTarget Initializer_opt`.
interface AssignmentTargetWithInitializer : Node {
attribute AssignmentTarget binding;
attribute Expression init;
};
// `ArrayAssignmentPattern`
interface ArrayAssignmentTarget : Node {
// The elements of the array pattern; a null value represents an elision.
attribute FrozenArray<(AssignmentTarget or AssignmentTargetWithInitializer?)> elements;
attribute AssignmentTarget? rest;
};
// `AssignmentProperty :: IdentifierReference Initializer_opt`
interface AssignmentTargetPropertyIdentifier : Node {
attribute AssignmentTargetIdentifier binding;
attribute Expression? init;
};
// `AssignmentProperty :: PropertyName : Node`
interface AssignmentTargetPropertyProperty : Node {
attribute PropertyName name;
attribute (AssignmentTarget or AssignmentTargetWithInitializer) binding;
};
typedef (AssignmentTargetPropertyIdentifier or
AssignmentTargetPropertyProperty)
AssignmentTargetProperty;
// `ObjectAssignmentPattern`
interface ObjectAssignmentTarget : Node {
attribute FrozenArray<AssignmentTargetProperty> properties;
};
// classes
interface ClassExpression : Node {
attribute BindingIdentifier? name;
attribute Expression? super;
attribute FrozenArray<ClassElement> elements;
};
interface ClassDeclaration : Node {
attribute BindingIdentifier name;
attribute Expression? super;
attribute FrozenArray<ClassElement> elements;
};
interface ClassElement : Node {
// True iff `IsStatic` of ClassElement is true.
attribute boolean isStatic;
attribute MethodDefinition method;
};
// modules
interface Module : Node {
attribute AssertedVarScope scope;
attribute FrozenArray<Directive> directives;
attribute FrozenArray<(ImportDeclaration or ExportDeclaration or Statement)> items;
};
// An `ImportDeclaration` not including a namespace import.
interface Import : Node {
attribute string moduleSpecifier;
// `ImportedDefaultBinding`, if present.
attribute BindingIdentifier? defaultBinding;
attribute FrozenArray<ImportSpecifier> namedImports;
};
// An `ImportDeclaration` including a namespace import.
interface ImportNamespace : Node {
attribute string moduleSpecifier;
// `ImportedDefaultBinding`, if present.
attribute BindingIdentifier? defaultBinding;
attribute BindingIdentifier namespaceBinding;
};
interface ImportSpecifier : Node {
// The `IdentifierName` in the production `ImportSpecifier :: IdentifierName as ImportedBinding`;
// absent if this specifier represents the production `ImportSpecifier :: ImportedBinding`.
attribute IdentifierName? name;
attribute BindingIdentifier binding;
};
// `export * FromClause;`
interface ExportAllFrom : Node {
attribute string moduleSpecifier;
};
// `export ExportClause FromClause;`
interface ExportFrom : Node {
attribute FrozenArray<ExportFromSpecifier> namedExports;
attribute string moduleSpecifier;
};
// `export ExportClause;`
interface ExportLocals : Node {
attribute FrozenArray<ExportLocalSpecifier> namedExports;
};
// `export VariableStatement`, `export Declaration`
interface Export : Node {
attribute (FunctionDeclaration or ClassDeclaration or VariableDeclaration) declaration;
};
// `export default HoistableDeclaration`,
// `export default ClassDeclaration`,
// `export default AssignmentExpression`
interface ExportDefault : Node {
attribute (FunctionDeclaration or ClassDeclaration or Expression) body;
};
// `ExportSpecifier`, as part of an `ExportFrom`.
interface ExportFromSpecifier : Node {
// The only `IdentifierName in `ExportSpecifier :: IdentifierName`,
// or the first in `ExportSpecifier :: IdentifierName as IdentifierName`.
attribute IdentifierName name;
// The second `IdentifierName` in `ExportSpecifier :: IdentifierName as IdentifierName`,
// if that is the production represented.
attribute IdentifierName? exportedName;
};
// `ExportSpecifier`, as part of an `ExportLocals`.
interface ExportLocalSpecifier : Node {
// The only `IdentifierName in `ExportSpecifier :: IdentifierName`,
// or the first in `ExportSpecifier :: IdentifierName as IdentifierName`.
attribute IdentifierExpression name;
// The second `IdentifierName` in `ExportSpecifier :: IdentifierName as IdentifierName`, if present.
attribute IdentifierName? exportedName;
};
// property definition
// `MethodDefinition :: PropertyName ( UniqueFormalParameters ) { FunctionBody }`,
// `GeneratorMethod :: * PropertyName ( UniqueFormalParameters ) { GeneratorBody }`,
// `AsyncMethod :: async PropertyName ( UniqueFormalParameters ) { AsyncFunctionBody }`
interface EagerMethod : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute PropertyName name;
// `length` property of this method.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
attribute FunctionOrMethodContents contents;
};
interface LazyMethod : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute PropertyName name;
// `length` property of this method.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
[Lazy] attribute FunctionOrMethodContents contents;
};
// `get PropertyName ( ) { FunctionBody }`
interface EagerGetter : Node {
attribute PropertyName name;
attribute FrozenArray<Directive> directives;
attribute GetterContents contents;
};
interface LazyGetter : Node {
attribute PropertyName name;
attribute FrozenArray<Directive> directives;
[Lazy] attribute GetterContents contents;
};
interface GetterContents : Node {
attribute boolean isThisCaptured;
attribute AssertedVarScope bodyScope;
attribute FunctionBody body;
};
// `set PropertyName ( PropertySetParameterList ) { FunctionBody }`
interface EagerSetter : Node {
attribute PropertyName name;
// `length` property of this setter function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
attribute SetterContents contents;
};
interface LazySetter : Node {
attribute PropertyName name;
// `length` property of this setter function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
[Lazy] attribute SetterContents contents;
};
interface SetterContents : Node {
attribute boolean isThisCaptured;
attribute AssertedParameterScope parameterScope;
attribute Parameter param;
attribute AssertedVarScope bodyScope;
attribute FunctionBody body;
};
// `PropertyDefinition :: PropertyName : AssignmentExpression`
interface DataProperty : Node {
attribute PropertyName name;
// The `AssignmentExpression`.
attribute Expression expression;
};
// `PropertyDefinition :: IdentifierReference`
interface ShorthandProperty : Node {
// The `IdentifierReference`.
attribute IdentifierExpression name;
};
interface ComputedPropertyName : Node {
attribute Expression expression;
};
// `LiteralPropertyName`
interface LiteralPropertyName : Node {
attribute string value;
};
// literals
// `BooleanLiteral`
interface LiteralBooleanExpression : Node {
attribute boolean value;
};
// A `NumericLiteral` for which the Number value of its MV is positive infinity.
interface LiteralInfinityExpression : Node { };
// `NullLiteral`
interface LiteralNullExpression : Node { };
// `NumericLiteral`
interface LiteralNumericExpression : Node {
attribute double value;
};
// `RegularExpressionLiteral`
interface LiteralRegExpExpression : Node {
attribute string pattern;
attribute string flags;
};
// `StringLiteral`
interface LiteralStringExpression : Node {
attribute string value;
};
// other expressions
// `ArrayLiteral`
interface ArrayExpression : Node {
// The elements of the array literal; a null value represents an elision.
attribute FrozenArray<(SpreadElement or Expression)?> elements;
};
// `ArrowFunction`,
// `AsyncArrowFunction`
interface EagerArrowExpressionWithFunctionBody : Node {
// True for `AsyncArrowFunction`, false otherwise.
attribute boolean isAsync;
// `length` property of this arrow function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
attribute ArrowExpressionContentsWithFunctionBody contents;
};
interface LazyArrowExpressionWithFunctionBody : Node {
// True for `AsyncArrowFunction`, false otherwise.
attribute boolean isAsync;
// `length` property of this arrow function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
[Lazy] attribute ArrowExpressionContentsWithFunctionBody contents;
};
interface EagerArrowExpressionWithExpression : Node {
// True for `AsyncArrowFunction`, false otherwise.
attribute boolean isAsync;
// `length` property of this arrow function.
attribute unsigned long length;
attribute ArrowExpressionContentsWithExpression contents;
};
interface LazyArrowExpressionWithExpression : Node {
// True for `AsyncArrowFunction`, false otherwise.
attribute boolean isAsync;
// `length` property of this arrow function.
attribute unsigned long length;
[Lazy] attribute ArrowExpressionContentsWithExpression contents;
};
interface ArrowExpressionContentsWithFunctionBody : Node {
attribute AssertedParameterScope parameterScope;
attribute FormalParameters params;
attribute AssertedVarScope bodyScope;
attribute FunctionBody body;
};
interface ArrowExpressionContentsWithExpression : Node {
attribute AssertedParameterScope parameterScope;
attribute FormalParameters params;
attribute AssertedVarScope bodyScope;
attribute Expression body;
};
// `AssignmentExpression :: LeftHandSideExpression = AssignmentExpression`
interface AssignmentExpression : Node {
// The `LeftHandSideExpression`.
attribute AssignmentTarget binding;
// The `AssignmentExpression` following the `=`.
attribute Expression expression;
};
// `ExponentiationExpression`,
// `MultiplicativeExpression`,
// `AdditiveExpression`,
// `ShiftExpression`,
// `RelationalExpression`,
// `EqualityExpression`,
// `BitwiseANDExpression`,
// `BitwiseXORExpression`,
// `BitwiseORExpression`,
// `LogicalANDExpression`,
// `LogicalORExpression`
interface BinaryExpression : Node {
attribute BinaryOperator operator;
// The expression before the operator.
attribute Expression left;
// The expression after the operator.
attribute Expression right;
};
interface CallExpression : Node {
attribute (Expression or Super) callee;
attribute Arguments arguments;
};
// `AssignmentExpression :: LeftHandSideExpression AssignmentOperator AssignmentExpression`
interface CompoundAssignmentExpression : Node {
attribute CompoundAssignmentOperator operator;
// The `LeftHandSideExpression`.
attribute SimpleAssignmentTarget binding;
// The `AssignmentExpression`.
attribute Expression expression;
};
interface ComputedMemberExpression : Node {
// The object whose property is being accessed.
attribute (Expression or Super) _object;
// The expression resolving to the name of the property to be accessed.
attribute Expression expression;
};
// `ConditionalExpression :: LogicalORExpression ? AssignmentExpression : AssignmentExpression`
interface ConditionalExpression : Node {
// The `LogicalORExpression`.
attribute Expression test;
// The first `AssignmentExpression`.
attribute Expression consequent;
// The second `AssignmentExpression`.
attribute Expression alternate;
};
// `FunctionExpression`,
// `GeneratorExpression`,
// `AsyncFunctionExpression`,
interface EagerFunctionExpression : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute BindingIdentifier? name;
// `length` property of this function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
attribute FunctionExpressionContents contents;
};
interface LazyFunctionExpression : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute BindingIdentifier? name;
// `length` property of this function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
[Lazy] attribute FunctionExpressionContents contents;
};
interface FunctionExpressionContents : Node {
attribute boolean isFunctionNameCaptured;
attribute boolean isThisCaptured;
attribute AssertedParameterScope parameterScope;
attribute FormalParameters params;
attribute AssertedVarScope bodyScope;
attribute FunctionBody body;
};
// `IdentifierReference`
interface IdentifierExpression : Node {
attribute Identifier name;
};
interface NewExpression : Node {
attribute Expression callee;
attribute Arguments arguments;
};
interface NewTargetExpression : Node { };
interface ObjectExpression : Node {
attribute FrozenArray<ObjectProperty> properties;
};
interface UnaryExpression : Node {
attribute UnaryOperator operator;
attribute Expression operand;
};
interface StaticMemberExpression : Node {
// The object whose property is being accessed.
attribute (Expression or Super) _object;
// The name of the property to be accessed.
attribute IdentifierName property;
};
// `TemplateLiteral`,
// `MemberExpression :: MemberExpression TemplateLiteral`,
// `CallExpression : CallExpression TemplateLiteral`
interface TemplateExpression : Node {
// The second `MemberExpression` or `CallExpression`, if present.
attribute Expression? tag;
// The contents of the template. This list must be alternating
// TemplateElements and Expressions, beginning and ending with
// TemplateElement.
attribute FrozenArray<(Expression or TemplateElement)> elements;
};
// `PrimaryExpression :: this`
interface ThisExpression : Node { };
// `UpdateExpression :: LeftHandSideExpression ++`,
// `UpdateExpression :: LeftHandSideExpression --`,
// `UpdateExpression :: ++ LeftHandSideExpression`,
// `UpdateExpression :: -- LeftHandSideExpression`
interface UpdateExpression : Node {
// True for `UpdateExpression :: ++ LeftHandSideExpression` and
// `UpdateExpression :: -- LeftHandSideExpression`, false otherwise.
attribute boolean isPrefix;
attribute UpdateOperator operator;
attribute SimpleAssignmentTarget operand;
};
// `YieldExpression :: yield`,
// `YieldExpression :: yield AssignmentExpression`
interface YieldExpression : Node {
// The `AssignmentExpression`, if present.
attribute Expression? expression;
};
// `YieldExpression :: yield * AssignmentExpression`
interface YieldStarExpression : Node {
attribute Expression expression;
};
interface AwaitExpression : Node {
attribute Expression expression;
};
// other statements
interface BreakStatement : Node {
attribute Label? label;
};
interface ContinueStatement : Node {
attribute Label? label;
};
interface DebuggerStatement : Node { };
interface DoWhileStatement : Node {
attribute Expression test;
attribute Statement body;
};
interface EmptyStatement : Node { };
interface ExpressionStatement : Node {
attribute Expression expression;
};
interface ForInOfBinding : Node {
attribute VariableDeclarationKind kind;
attribute Binding binding;
};
// `for ( LeftHandSideExpression in Expression ) Statement`,
// `for ( var ForBinding in Expression ) Statement`,
// `for ( ForDeclaration in Expression ) Statement`,
// `for ( var BindingIdentifier Initializer in Expression ) Statement`
interface ForInStatement : Node {
// The expression or declaration before `in`.
attribute (ForInOfBinding or AssignmentTarget) left;
// The expression after `in`.
attribute Expression right;
attribute Statement body;
};
// `for ( LeftHandSideExpression of Expression ) Statement`,
// `for ( var ForBinding of Expression ) Statement`,
// `for ( ForDeclaration of Expression ) Statement`
interface ForOfStatement : Node {
// The expression or declaration before `of`.
attribute (ForInOfBinding or AssignmentTarget) left;
// The expression after `of`.
attribute Expression right;
attribute Statement body;
};
// `for ( Expression ; Expression ; Expression ) Statement`,
// `for ( var VariableDeclarationList ; Expression ; Expression ) Statement`
interface ForStatement : Node {
// The expression or declaration before the first `;`, if present.
attribute (VariableDeclaration or Expression)? init;
// The expression before the second `;`, if present
attribute Expression? test;
// The expression after the second `;`, if present
attribute Expression? update;
attribute Statement body;
};
// `if ( Expression ) Statement`,
// `if ( Expression ) Statement else Statement`,
interface IfStatement : Node {
attribute Expression test;
// The first `Statement`.
attribute Statement consequent;
// The second `Statement`, if present.
attribute Statement? alternate;
};
interface LabelledStatement : Node {
attribute Label label;
attribute Statement body;
};
interface ReturnStatement : Node {
attribute Expression? expression;
};
// A `SwitchStatement` whose `CaseBlock` is
// `CaseBlock :: { CaseClauses }`.
interface SwitchStatement : Node {
attribute Expression discriminant;
attribute FrozenArray<SwitchCase> cases;
};
// A `SwitchStatement` whose `CaseBlock` is
// `CaseBlock :: { CaseClauses DefaultClause CaseClauses }`.
interface SwitchStatementWithDefault : Node {
attribute Expression discriminant;
// The `CaseClauses` before the `DefaultClause`.
attribute FrozenArray<SwitchCase> preDefaultCases;
// The `DefaultClause`.
attribute SwitchDefault defaultCase;
// The `CaseClauses` after the `DefaultClause`.
attribute FrozenArray<SwitchCase> postDefaultCases;
};
interface ThrowStatement : Node {
attribute Expression expression;
};
// `TryStatement :: try Block Catch`
interface TryCatchStatement : Node {
attribute Block body;
attribute CatchClause catchClause;
};
// `TryStatement :: try Block Finally`,
// `TryStatement :: try Block Catch Finally`
interface TryFinallyStatement : Node {
// The `Block`.
attribute Block body;
// The `Catch`, if present.
attribute CatchClause? catchClause;
// The `Finally`.
attribute Block finalizer;
};
interface WhileStatement : Node {
attribute Expression test;
attribute Statement body;
};
interface WithStatement : Node {
attribute Expression _object;
attribute Statement body;
};
// other nodes
interface Block : Node {
attribute AssertedBlockScope scope;
attribute FrozenArray<Statement> statements;
};
// `Catch`
interface CatchClause : Node {
attribute AssertedBoundNamesScope bindingScope;
attribute Binding binding;
attribute Block body;
};
// An item in a `DirectivePrologue`
interface Directive : Node {
attribute string rawValue;
};
interface FormalParameters : Node {
attribute FrozenArray<Parameter> items;
attribute Binding? rest;
};
typedef FrozenArray<Statement> FunctionBody;
// `FunctionDeclaration`,
// `GeneratorDeclaration`,
// `AsyncFunctionDeclaration`
interface EagerFunctionDeclaration : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute BindingIdentifier name;
// `length` property of this function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
attribute FunctionOrMethodContents contents;
};
interface LazyFunctionDeclaration : Node {
attribute boolean isAsync;
attribute boolean isGenerator;
attribute BindingIdentifier name;
// `length` property of this function.
attribute unsigned long length;
attribute FrozenArray<Directive> directives;
[Lazy] attribute FunctionOrMethodContents contents;
};
interface FunctionOrMethodContents : Node {
attribute boolean isThisCaptured;
attribute AssertedParameterScope parameterScope;
attribute FormalParameters params;
attribute AssertedVarScope bodyScope;
attribute FunctionBody body;
};
interface Script : Node {
attribute AssertedScriptGlobalScope scope;
attribute FrozenArray<Directive> directives;
attribute FrozenArray<Statement> statements;
};
interface SpreadElement : Node {
attribute Expression expression;
};
// `super`
interface Super : Node { };
// `CaseClause`
interface SwitchCase : Node {
attribute Expression test;
attribute FrozenArray<Statement> consequent;
};
// `DefaultClause`
interface SwitchDefault : Node {
attribute FrozenArray<Statement> consequent;
};
// `TemplateCharacters`
interface TemplateElement : Node {
attribute string rawValue;
};
interface VariableDeclaration : Node {
attribute VariableDeclarationKind kind;
[NonEmpty] attribute FrozenArray<VariableDeclarator> declarators;
};
interface VariableDeclarator : Node {
attribute Binding binding;
attribute Expression? init;
};
The
A Parse Node may be tagged as being transformed by a
The current asserted scope is used to track asserted scopes during transformation of binary AST Nodes.
The naming convention of the
Bar
and returns Parse Nodes of varying ECMAScript grammar productions.Statement
.Block
, thenIterationStatement
, thenFrozenArray<Statement>
.FunctionDeclaration
, thenExpressionStatement
and stmt.expression
is a LiteralStringExpression
:.expression
).FrozenArray<VariableDeclarator>
..binding
)..init
is .binding
is not a BindingIdentifier
, throw a .init
).FrozenArray<VariableDeclarator>
..binding
)..init
is .binding
is not a BindingIdentifier
, throw a .init
).FrozenArray<SpreadElement or Expression>
..expression
).FrozenArray<Parameter>
.Arguments
.SpreadElement
, then.expression
).FrozenArray<ObjectProperty>
or a `FrozenArray<AssignmentTargetProperty>.MethodDefinition
, then let n be SwitchCase
..consequent
has length 0, then.consequent
).SwitchDefault
..consequent
has length 0, thenFrozenArray<SwitchCase>
.Arguments
..arguments
).Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.ThisExpression
, then return ? IdentifierExpression
, a Literal
, an ArrayExpression
, an ObjectExpression
, a FunctionExpression
, a ClassExpression
, a LiteralRegExpExpression
, a TemplateExpression
, an AssignmentTargetIdentifier
, an ArrayAssignmentExpression
, or an ObjectAssignmentExpression
, then return Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.ComputedMemberExpression
, a StaticMemberExpression
, a NewTargetExpression
, a NewExpression
, a ComputedMemberAssignmentTarget
, or a StaticMemberAssignmentTarget
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.NewExpression
, thenCallExpression
, then return Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.UpdateExpression
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.UnaryExpression
, then return ? AwaitExpression
, thenExpression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.BinaryExpression
and e.operator
is "||"
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.BinaryExpression
and e.operator
is "|"
, "/"
, or "%"
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.BinaryExpression
and e.operator
is "+"
or "-"
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.BinaryExpression
and e.operator
is "<<"
, ">>"
, or ">>>"
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.BinaryExpression
and e.operator
is "<"
, ">"
, "<="
, ">="
, "instanceof"
, or "in"
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.BinaryExpression
and e.operator
is "=="
, "!="
, "==="
, or "!=="
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.BinaryExpression
and e.operator
is "&"
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.BinaryExpression
and e.operator
is "^"
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.BinaryExpression
and e.operator
is "|"
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.BinaryExpression
and e.operator
is "&&"
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.BinaryExpression
and e.operator
is "||"
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.ConditionalExpression
, then return ? Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.AssignmentExpression
, a CompoundAssignmentExpression
, or an AssignmentTargetWithInitializer
, then return ? YieldExpression
or an ArrowExpression
, then return Expression
, an AssignmentTarget
, or an AssignmentTargetWithInitializer
.BinaryExpression
and e.operator
is ","
, then return ? LazyFunctionDeclaration
, a LazyFunctionExpression
, a LazyMethod
, a LazyGetter
, a LazySetter
, or a LazyArrowExpression
, then return.LazyFunctionExpression
, then return..contents.isFunctionNameCaptured
is FormalParameters
is evaluated at runtime, LazyFunctionDeclaration
, a LazyFunctionExpression
, or a LazyMethod
, then.contents.params
..contents.parameterScope
.FormalParameters
.FormalParameters
is evaluated at runtime, LazyArrowExpression
, then.content.params
..content.parameterScope
.FormalParameters
.Parameter
is evaluated at runtime, LazySetter
, then.contents.param
..contents.parameterScope
.Parameter
.LazyFunctionDeclaration
, a LazyFunctionExpression
, a LazyMethod
, a LazyGetter
, a LazySetter
, or a LazyArrowExpression
, then.contents
..bodyScope
.ArrowExpressionContents
, then perform ? Identifier
or an IdentifierName
.Label
."yield"
, then return "await"
, then return Expression
.FrozenArray<BindingProperty>
.FrozenArray<(Binding or BindingWithInitializer)>
.Binding or BindingWithInitializer
.BindingWithInitializer
, then return elem0.BindingIdentifier
, thenBinding
.BindingPattern
, then let restElem0 be Script
..scope
..scope
, enclosingScope)..directives
prepended to s.statements
..directives
has length 0 and s.statements
has length 0, then.directives
concatenated with s.statements
..scope
, script).Module
.FormalParameters
is evaluated.FormalParameters
..items
has length 0, then.rest
is null, then return .rest
)..items
)..rest
is null, then return .rest
).FormalParameters
is evaluated.FormalParameters
.Parameter
.FunctionBody
is evaluated.FunctionDeclaration
, a FunctionExpression
, a Method
, a Getter
, a Setter
, or a ArrowExpression
..contents.body
is a FunctionBody
, thenArrowExpression
and f.directives
is .directives
concatenated with f.contents.body
..contents.body
is an Expression
..directives
is not .contents.body
) Block
..scope
..scope
, enclosingScope)..statements
)..scope
, block).Directive
..rawValue
escaped for double quotes.BreakStatement
..label
is .label
) ContinueStatement
..label
is .label
) ClassDeclaration
.DebuggerStatement
.EmptyStatement
.ExpressionStatement
..expression
) EagerFunctionDeclaration
or a LazyFunctionDeclaration
..name
)..isAsync
is .isGenerator
is *
IfStatement
..test
)..consequent
)..alternate
is .alternate
).
DoWhileStatement
..test
)..body
).ForInStatement
..right
)..body
)..left
is a ForInOfBinding
, then.left.kind
is "var"
, then.left.binding
)..left
)..left
).ForOfStatement
..right
)..body
)..left
is a ForInOfBinding
, then.left.kind
is "var"
, then.left.binding
)..left
)..left
).ForStatement
..test
is not null, then set test to ? .test
)..update
is not null, then set update to ? ExperssionEcmaify(for.test
)..body
)..init
is not .init
is a VariableDeclaration
, then.init.kind
is "var"
, then.init.declarators
)..init.kind
) ? .init.declarators
)..init
).WhileStatement
..test
)..body
).LabelledStatement
..body
is a FunctionDeclaration
, then.body.isAsync
is true or labelled.body.isGenerator
is .body
)..body
)..label
) ReturnStatement
..expression
is .expression
).
SwitchStatement
..discriminant
)..cases
has length 0, then set block to .cases
).SwitchStatementWithDefault
..discriminant
)..defaultCase
)..preDefaultCases
has length 0, then.postDefaultCases
has length 0, then.postDefaultCases
)..postDefaultCases
has length 0, then.preDefaultCases
)..preDefaultCases
)..postDefaultCases
).ThrowStatement
..expression
).
TryCatchStatement
..body
)..catchClause
).TryFinallyStatement
..body
)..finalizer
)..catch
is .catchClause
).VariableDeclaration
..kind
is "var"
, then.declarators
)..kind
)..declarators
).WithStatement
.._object
)..body
).LiteralBooleanExpression
..value
is Infinity
identifier, but for literal decimals whose mathematical values exceed the bounds of IEEE doubles.LiteralInfinityExpresion
.LiteralNullExpression
.LiteralNumericExpression
..value
.LiteralRegExpExpression
..pattern
..flags
.LiteralStringExpression
..value
escaped for double quotes.ArrayExpression
or an ArrayAssignmentTarget
.ArrayAssignmentTarget
directly to .elements
has length 0, then.elements
).EagerArrowExpression
or a LazyArrowExpression
..isAsync
is AssignmentExpression
..binding
)..expression
).BinaryExpression
..operator
is ","
, then.left
)..right
)..operator
is "||"
, then.left
)..right
)..operator
is "&&"
, then.left
)..right
)..operator
is "|"
, then.left
)..right
).|
.operator
is "^"
, then.left
)..right
)..operator
is "&"
, then.left
)..right
)..operator
is "=="
, "!="
, "==="
, or "!=="
, then.left
)..right
)..operator
is "=="
, then return .operator
is "!="
, then return .operator
is "==="
, then return .operator
is "<"
, ">"
, "<="
, ">="
, "instanceof"
, or "in"
, then.left
)..right
)..operator
is "<"
return .operator
is ">"
, then return .operator
is "<="
return .operator
is ">="
, then return .operator
is "instanceof"
, then return .operator
is "<<"
, ">>"
, or ">>>"
, then.left
)..right
)..operator
is "<<"
, then return .operator
is ">>"
, then return .operator
is "+"
or "-"
, then.left
)..right
)..operator
is "+"
, then return .operator
is "*"
, "/"
, or "%"
, then.left
)..right
)..operator
is "*"
, then set op to *
.operator
is "/"
, then set op to .operator
is "%"
, then set op to .left
)..right
).**
CallExpression
..arguments
).Super
, then.callee
).CompoundAssignmentExpression
..binding
).expression
)..operator
is "|="
then set op to .operator
is "/="
then set op to .operator
is "%="
then set op to .operator
is "+="
then set op to .operator
is "-="
then set op to .operator
is "<<="
then set op to .operator
is ">>="
then set op to .operator
is ">>>="
then set op to .operator
is "&="
then set op to .operator
is "^="
then set op to .operator
is "|="
then set op to ComputedMemberExpression
or a ComputedMemberAssignmentTarget
..expression
).._object
is a Super
, then._object
).ConditionalExpression
..test
)..consequent
)..alternate
).ClassExpression
.EagerFunctionExpression
or a LazyFunctionExpression
..name
not .name
)..isAsync
is .isGenerator
is *
IdentifierExpression
..name
is "yield"
, then return .name
is "await"
, then return .name
).
NewExpression
..callee
)..arguments
).NewTargetExpression
.ObjectExpression
or an ObjectAssignmentTarget
.ObjectAssignmentTarget
directly to .properties
has length 0, then return .properties
).UnaryExpression
..operand
)..operator
is "delete", then return .operator
is "void", then return .operator
is "typeof", then return .operator
is "+", then return .operator
is "-", then return .operator
is "StaticMemberExpression
or a StaticMemberAssignmentTarget
.._object
is a Super
, then.property
.._object
)..property
.
TemplateExpression
.ThisExpression
.UpdateExpression
..isPrefix
is .operand
)..operator
is "++"
, then return .operand
)..operator
is "++"
, then return YieldExpression
..expression
is null, then.expression
).YieldStarExpression
..expression
).*
AwaitExpression
..expression
).ComputedPropertyName
..expression
).LiteralPropertyName
..value
is the empty string, then throw a .value
escaped for double quotes.EagerMethod
or a LazyMethod
..name
)..isAsync
is .isGenerator
is *
EagerGetter
or a LazyGetter
..name
).EagerSetter
or a LazySetter
..name
)..param
).DataProperty
..name
)..expression
).ShorthandProperty
..name
).BindingIdentifier
..name
is "yield"
, then return .name
is "await"
, then return .name
).
ObjectBinding
..properties
has length 0, then return .properties
) BindingPropertyIdentifier
..binding
)..init
is not .init
).BindingPropertyProperty
..name
).ArrayBinding
..elements
has length 0, then.rest
is .rest
)..elements
)..rest
is .rest
)..rest
is .rest
).BindingWithInitializer
..binding
)..init
)..binding
is a BindingIdentifier
, thenAssignmentTargetWithInitializer
..binding
)..init
).AssignmentTargetPropertyIdentifier
..binding.name
)..init
is not .init
).AssignmentTargetPropertyProperty
..name
)..binding
).ForInOfBinding
..kind
is not "var"
..binding
)..kind
) binding.
Parameter
.CatchClause
..bindingScope
..bindingScope
, enclosingScope)..binding
)..body
)..bindingScope
, catch)."let"
or "const"
."let"
, then return Node
.Block
, then return ? BreakStatement
, then return ? ContinueStatement
, then return ? ClassDeclaration
, then return ? DebuggerStatement
, then return ? EmptyStatement
, then return ? ExpressionStatement
, then return ? FunctionDeclaration
, then return ? IfStatement
, then return ? DoWhileStatement
, then return ? ForInStatement
, then return ? ForOfStatement
, then return ? ForStatement
, then return ? WhileStatement
, then return ? LabelledStatement
, then return ? ReturnStatement
, then return ? SwitchStatement
, then return ? SwitchStatementWithDefault
, then return ? ThrowStatement
, then return ? TryCatchStatement
, then return ? TryFinallyStatement
, then return ? VariableDeclaration
, then return ? WithStatement
, then return ? LiteralBooleanExpression
, then return ? LiteralInfinityExpression
, then return ? LiteralNullExpression
, then return ? LiteralNumericExpression
, then return ? LiteralStringExpression
, then return ? LiteralRegExpExpression
, then return ? ArrayExpression
, then return ? ArrowExpression
, then return ? AssignmentExpression
, then return ? BinaryExpression
, then return ? CallExpression
, then return ? CompoundAssignmentExpression
, then return ? ComputedMemberExpression
, then return ? ConditionalExpression
, then return ? ClassExpression
, then return ? FunctionExpression
, then return ? IdentifierExpression
, then return ? NewExpression
, then return ? NewTargetExpression
, then return ? ObjectExpression
, then return ? UnaryExpression
, then return ? StaticMemberExpression
, then return ? TemplateExpression
, then return ? ThisExpression
, then return ? UpdateExpression
, then return ? YieldExpression
, then return ? YieldStarExpression
, then return ? AwaitExpression
, then return ? ComputedPropertyName
, then return ? LiteralPropertyName
, then return ? LiteralPropertyName
, then return ? Method
, then return ? Getter
, then return ? Setter
, then return ? DataProperty
, then return ? ShorthandProperty
, then return ? ExportAllFrom
, then return ? EcmaifyExportAllFrom(node).ExportFrom
, then return ? EcmaifyExportFrom(node).ExportLocals
, then return ? EcmaifyExportLocals(node).ExportDefault
, then return ? EcmaifyExportDefault(node).ExportFromSpecifier
, then return ? EcmaifyExportFromSpecifier(node).ExportLocalSpecifier
, then return ? EcmaifyExportLocalSpecifier(node).Export
, then return ? EcmaifyExport(node).ImportSpecifier
, then return ? EcmaifyImportSpecifier(node).ImportNamespace
, then return ? EcmaifyImportNamespace(node).Import
, then return ? EcmaifyImport(node).BindingIdentifier
, then return ? ObjectBinding
, then return ? BindingPropertyIdentifier
, then return ? BindingPropertyProperty
, then return ? ArrayBinding
, then return ? BindingWithInitializer
, then return ? AssignmentTarget
nodes are transformed as expressions instead of the cover grammar variant as the ECMAScript spec does reparsing.AssignmentTargetIdentifier
, then return ? EcmaifyAssignmentTargetIdentifierExpression(node).AssignmentTargetWithInitializer
, then return ? ComputedMemberAssignmentTarget
, then return ? StaticMemberAssignmentTarget
, then return ? ObjectAssignmentTarget
, then return ? AssignmentTargetPropertyIdentifier
, then return ? AssignmentTargetPropertyProperty
, then return ? ArrayAssignmentTarget
, then return ? ClassElement
, then return ? EcmaifyClassElement(node).ForInOfBinding
, then return ? Binary AST is evaluated via the modified
Evaluation of binary AST is possibly lazy at function boundaries. Together with AssertedScope
, the intent is to allow implementations to start to start code generation without parsing the entire tree. AssertedScope
represent assertions that must be checked. A failing assertion throws a
Asserted declared names must match exactly the set of actual declared names exactly in the scope. The asserted captured names in the scope must be a superset of observed captured names. If the presence of
The GlobalAssertedScopeTree is a
Field Name | Value | Meaning |
---|---|---|
[[AssertedScope]] |
An AssertedBlockScope , AssertedScriptGlobalScope , AssertedVarScope , AssertedParameterScope , or AssertedBoundNamesScope
|
The payload. |
[[Enclosing]] |
An AssertedScopeTreeNode |
The directly enclosing scope. |
.kind
is kind, then add d.name
as the last element of unseen..name
as the last element of expectedParams.[idx]
is not pn, then throw a AssertedPositionalParameterName
, then.name
and item.[[Index]] is p.index
, thenAssertedRestParameterName
, then.name
, then.name
as the last element of unseen.AssertedBlockScope
or an AssertedScriptGlobalScope
or an AssertedVarScope
or an AssertedParameterScope
or an AssertedBoundNamesScope
.AssertedBlockScope
or an AssertedScriptGlobalScope
or an AssertedVarScope
, then.declaredNames
, "var"
, varDeclaredNames)..declaredNames
, "const lexical"
, constLexicallyDeclaredNames)..declaredNames
, "non-const lexical"
, nonConstLexicallyDeclaredNames).AssertedParameterScope
, then.paramNames
, paramNames)..paramNames
, positionalParamNames)..paramNames
, restParameterName)..isSimpleParameterList
is not the same value as IsSimpleParameterList of parseTree, then throw a .boundNames
, boundNames).AssertedBlockScope
or an AssertedScriptGlobalScope
or an AssertedVarScope
, then.declaredNames
.AssertedParameterScope
, then,.paramNames
..boundNames
..name
, then.isCaptured
is AssertedScriptGlobalScope
, then throw a .hasDirectEval
is AssertedVarScope
or an AssertedParameterScope
.AssertedBlockScope
, then.declaredNames
has a single item d and d.name
is "this"
, then.isCaptured
is this
binding captured by a nested arrow. Synthesize a scope that encloses the parameter and body scopes of the function body that contains the sole binding this
. It is checked by EagerArrowExpression
nor a LazyArrowExpression
.AssertedBlockScope
.AssertedDeclaredName
..name
to "this"
..kind
to "non-const lexical"
..contents.isThisCaptured
is .isCaptured
to .declaredNames
to be a new FrozenArray<AssertedDeclaredName>
of length 1 containing thisDecl..hasDirectEval
to enclosingScope.hasDirectEval
.AssertedBlockScope
.AssertedDeclaredName
..name
to funcExprNode.name
.const
, but it does not matter for the semantics of asserted scopes..kind
to "const lexical"
..isCaptured
to .declaredNames
to be a new FrozenArray<AssertedDeclaredName>
of length 1 containing namedLambdaDecl..hasDirectEval
to enclosingScope.hasDirectEval
.FunctionDeclaration
, a FunctionExpression
, a Method
, a Getter
, a Setter
, or an ArrowExpression
.Getter
, then.length
.FreeNames is a new Static Semantics that collects uses of unbound variables.
Unless overridden, Parse Nodes have the following default definition.
"yield"
».
"await"
».
HasFreeThis is a new Static Semantics that returns this
is free in the Parse Node (i.e. either used directly or in a nested arrow expression).
Unless overridden, Parse Nodes have the following default definition.
Collect the positional formal parameter names.
With parameters formalParameters.
"yield"
.
"await"
.
Return the rest parameter name.
With parameters formalParameters.
"yield"
.
"await"
.
When FormalParameters is tagged as being produced by lazyNode.
.length
.
The abstract operation RunJobs is modified as follows.
Script
ASTs, and/or ECMAScript Module
ASTs. For each such Script
, then"ScriptJobs"
, Module
,"ScriptJobs"
, The abstract operation ScriptEvaluationJob is modified as follows.
Script
(see TransformASTScript is a new abstract operation.
FunctionDeclaration
, then.name
)..isAsync
is .isGenerator
is *
ArrowExpression
, then.isAsync
is FunctionExpression
, then.name
not .name
)..isAsync
is .isGenerator
is *
Method
, then.name
)..isAsync
is .isGenerator
is *
Getter
, then.name
).Setter
..name
).Delazify is a new Runtime Semantics.
With parameter functionObject.
LazyFunctionDeclaration
, a LazyFunctionExpression
, a LazyMethod
, a LazyGetter
, a LazySetter
, or a LazyArrowExpression
..contents
.LazyFunctionExpression
, funcNode.name
is not .isFunctionNameCaptured
is LazyArrowExpression
, thenLazyGetter
, then.parameterScope
, scope)..parameterScope
..bodyScope
, scope)..bodyScope
.LazyGetter
, then perform ? .parameterScope
, delazifiedParams)..bodyScope
, delazifiedBody).LazyArrowExpression
, then.parameterScope
, delazifiedParams)..bodyScope
, delazifiedBody)..contents.parameterScope
..contents.params
)..contents.parameterScope
..contents.params
)..contents.parameterScope
..contents.param
).The runtime semantics of
With parameters functionObject and
"%GeneratorPrototype%"
, « [[GeneratorState]], [[GeneratorContext]] »).© 2018 Shu-yu Guo, David Teller, Ecma International
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:
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.