15.10.1 Статическая семантика: IsInTailPosition ( call )
Абстрактная операция IsInTailPosition (Находится в хвостовой позиции) принимает аргумент call. При вызове она выполняет следующие шаги:
1. Утверждено: вызов call является Узлом Синтаксического Анализа. 2. Если вызов call сопоставления исходного кода является нестрогим кодом, вернуть false. 3. Если вызов call не содержится в FunctionBody, ConciseBody или AsyncConciseBody, вернуть false. 4. Пусть body будет FunctionBody, ConciseBody или AsyncConciseBody, которые наиболее близко содержат call. 5. Если body является FunctionBody тела GeneratorBody, верните false. 6. Если body является FunctionBody для AsyncFunctionBody, верните false. 7. Если body является FunctionBody для AsyncGeneratorBody, верните false. 8. Если body является AsyncConciseBody, верните false. 9. Вернуть результат HasCallInTailPosition из тела body с аргументом вызова call.
Вызовы Tail Position определяются только в коде строгого режима из-за общего нестандартного расширения языка (см. 10.2.4), которое позволяет наблюдать цепочку контекстов вызывающего абонента.
15.10.2 Статическая семантика: Имеет Вызов В Хвостовой Позиции — HasCallInTailPosition
С параметром call
call — это узел синтаксического анализа, который представляет определенный диапазон исходного текста. Когда следующие алгоритмы сравнивают вызов call с другим узлом синтаксического анализа, это проверка того, представляют ли они один и тот же исходный текст.
15.10.2.1 Правила Заявления
StatementList : StatementList StatementListItem
1. Пусть has будет HasCallInTailPosition в StatementList с аргументом call. 2. Если has является true (истина), вернуть true (истину). 3. Верните HasCallInTailPosition из StatementListItem с аргументом call.
FunctionStatementList : [empty]
StatementListItem : Declaration
Block : { }
ReturnStatement : return ;
LabelledItem : FunctionDeclaration
for ( LeftHandSideExpression of AssignmentExpression ) Statement
for ( var ForBinding of AssignmentExpression ) Statement
for ( ForDeclaration of AssignmentExpression ) Statement
CaseBlock : { }
1. Вернуть false.
IfStatement : if ( Expression ) Statement else Statement
1. Пусть has будет HasCallInTailPosition первого утверждения Statement с аргументом call. 2. Если has является true (истина), вернуть true (истину). 3. Вернуть HasCallInTailPosition второго утверждения Statement с аргументом call.
IfStatement : if ( Expression ) Statement
DoWhileStatement : do Statement while ( Expression ) ;
WhileStatement : while ( Expression ) Statement
for ( Expression opt ; Expression opt ; Expression opt ) Statement
for ( var VariableDeclarationList ; Expression opt ; Expression opt ) Statement
for ( LexicalDeclaration Expression opt ; Expression opt ) Statement
for ( LeftHandSideExpression in Expression ) Statement
for ( var ForBinding in Expression ) Statement
for ( ForDeclaration in Expression ) Statement
for await ( LeftHandSideExpression of AssignmentExpression ) Statement
for await ( var ForBinding of AssignmentExpression ) Statement
for await ( ForDeclaration of AssignmentExpression ) Statement
WithStatement : with ( Expression ) Statement
1. Вернуть HasCallInTailPosition утверждения Statement с аргументом call.
LabelledStatement : LabelIdentifier : LabelledItem
1. Верните HasCallInTailPosition из LabelledItem с аргументом call.
ReturnStatement : return Expression ;
1. Верните HasCallInTailPosition выражения Expression с аргументом call.
SwitchStatement : switch ( Expression ) CaseBlock
1. Верните HasCallInTailPosition из CaseBlock с аргументом call.
CaseBlock : { CaseClauses opt DefaultClause CaseClauses opt }
1. Пусть has будет false (ложь). 2. Если присутствует первый объект CaseClauses, пусть has будет HasCallInTailPosition из первого объекта CaseClauses с аргументом call. 3. Если has является true (истина), вернуть true (истину). 4. Пусть будет HasCallInTailPosition из DefaultClause с аргументом call. 5. Если has является true (истина), вернуть true (истину). 6. Если присутствует второй объект CaseClauses, пусть будет HasCallInTailPosition второго объекта CaseClauses с аргументом call. 7. Вернуть has.
CaseClauses : CaseClauses CaseClause
1. Пусть будет HasCallInTailPosition из CaseClauses с аргументом call. 2. Если has является true (истина), вернуть true (истину). 3. Вернуть HasCallInTailPosition из CaseClause с аргументом call.
CaseClause : case Expression : StatementList opt
DefaultClause : default : StatementList opt
1. Если StatementList присутствует, верните HasCallInTailPosition из StatementList с аргументом call. 2. Вернуть false.
TryStatement : try Block Catch
1. Верните HasCallInTailPosition из Catch с аргументом call.
TryStatement : try Block Finally
TryStatement : try Block Catch Finally
1. Верните HasCallInTailPosition из Finally с аргументом call.
Catch : catch ( CatchParameter ) Block
1. Вернуть HasCallInTailPosition блока Block с аргументом call.
15.10.2.2 Правила выражения
Примечание
Вызов потенциальной позиции хвоста, за которым сразу следует возврат GetValue результата вызова, также является возможным вызовом позиции хвоста. Вызов функции не может вернуть ссылочную запись, поэтому такая операция GetValue всегда будет возвращать то же значение, что и фактический результат вызова функции.
LeftHandSideExpression = AssignmentExpression
LeftHandSideExpression AssignmentOperator AssignmentExpression
LeftHandSideExpression &&= AssignmentExpression
LeftHandSideExpression ||= AssignmentExpression
LeftHandSideExpression ??= AssignmentExpression
BitwiseANDExpression : BitwiseANDExpression & EqualityExpression
BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression
BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression
EqualityExpression == RelationalExpression
EqualityExpression != RelationalExpression
EqualityExpression === RelationalExpression
EqualityExpression !== RelationalExpression
RelationalExpression < ShiftExpression
RelationalExpression > ShiftExpression
RelationalExpression <= ShiftExpression
RelationalExpression >= ShiftExpression
RelationalExpression instanceof ShiftExpression
RelationalExpression in ShiftExpression
PrivateIdentifier in ShiftExpression
ShiftExpression << AdditiveExpression
ShiftExpression >> AdditiveExpression
ShiftExpression >>> AdditiveExpression
AdditiveExpression + MultiplicativeExpression
AdditiveExpression — MultiplicativeExpression
MultiplicativeExpression MultiplicativeOperator ExponentiationExpression
UpdateExpression ** ExponentiationExpression
delete UnaryExpression
void UnaryExpression
typeof UnaryExpression
CallExpression . IdentifierName
CallExpression . PrivateIdentifier
NewExpression : new NewExpression
MemberExpression [ Expression ]
MemberExpression . IdentifierName
new MemberExpression Arguments
MemberExpression . PrivateIdentifier
this
1. Вернуть false.
Expression , AssignmentExpression
1. Верните HasCallInTailPosition из AssignmentExpression с аргументом call.
ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
1. Пусть has будет HasCallInTailPosition первого AssignmentExpression с аргументом call. 2. Если has является true, вернуть true. 3. Верните HasCallInTailPosition второго AssignmentExpression с аргументом call.
LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
1. Верните HasCallInTailPosition из BitwiseORExpression с аргументом call.
LogicalORExpression : LogicalORExpression || LogicalANDExpression
1. Верните HasCallInTailPosition из LogicalANDExpression с аргументом call.
CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression
1. Верните HasCallInTailPosition из BitwiseORExpression с аргументом call.
CoverCallExpressionAndAsyncArrowHead
CallExpression TemplateLiteral
1. Если это CallExpression является call, верните true. 2. Вернуть false.
MemberExpression OptionalChain
OptionalExpression OptionalChain
1. Верните HasCallInTailPosition из OptionalChain с аргументом call.
?. [ Expression ]
OptionalChain . IdentifierName
OptionalChain . PrivateIdentifier
1. Вернуть false.
?. Arguments
1. Если этот OptionalChain является вызовом call, верните true. 2. Вернуть false.
MemberExpression TemplateLiteral
1. Если это MemberExpression является call, верните true. 2. Вернуть false.
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
1. Пусть expr будет ParenthesizedExpression, которое покрывается CoverParenthesizedExpressionAndArrowParameterList. 2. Вернуть HasCallInTailPosition выражения expr с аргументом call.
ParenthesizedExpression : ( Expression )
1. Верните HasCallInTailPosition выражения Expression с аргументом call.
15.10.3 PrepareForTailCall ( )
Абстрактная операция PrepareForTailCall () не принимает аргументов. При вызове она выполняет следующие шаги:
1. Пусть leafContext будет текущим контекстом выполнения. 2. Приостановить leafContext. 3. Извлеките leafContext из стека контекста выполнения. Контекст выполнения, который теперь находится на вершине стека, становится текущим контекстом выполнения. 4. Утверждено: leafContext больше не используется. Он никогда не будет активирован как текущий контекст выполнения.
Вызов конечной (хвостовой) позиции должен либо освободить любые временные внутренние ресурсы, связанные с текущим контекстом выполнения функции, перед вызовом целевой функции, либо повторно использовать эти ресурсы для поддержки целевой функции.
Например, вызов позиции хвоста должен увеличивать стек записей активации реализации только на величину, на которую размер записи активации целевой функции превышает размер записи активации вызывающей функции. Если запись активации целевой функции меньше, общий размер стека должен уменьшиться.
Информационные ссылки
Стандарт ECMAScript — Раздел «15.10 Tail Position Calls» — https://tc39.es/ecma262/#sec-tail-position-calls