ECMAScript | Вызовы Положения Хвоста (Tail Position Calls)

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

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. Вернуть 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

ForStatement :

for ( Expression opt ; Expression opt ; Expression opt ) Statement

for ( var VariableDeclarationList ; Expression opt ; Expression opt ) Statement

for ( LexicalDeclaration Expression opt ; Expression opt ) Statement

ForInOfStatement :

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 всегда будет возвращать то же значение, что и фактический результат вызова функции.

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

1. Вернуть false.

Expression :

AssignmentExpression

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.

CallExpression :

CoverCallExpressionAndAsyncArrowHead

CallExpression Arguments

CallExpression TemplateLiteral

1. Если это CallExpression является call, верните true.
2. Вернуть false.

OptionalExpression :

MemberExpression OptionalChain

CallExpression OptionalChain

OptionalExpression OptionalChain

1. Верните HasCallInTailPosition из OptionalChain с аргументом call.

OptionalChain :

?. [ Expression ]

?. IdentifierName

?. PrivateIdentifier

OptionalChain [ Expression ]

OptionalChain . IdentifierName

OptionalChain . PrivateIdentifier

1. Вернуть false.

OptionalChain :

?. Arguments

OptionalChain Arguments

1. Если этот OptionalChain является вызовом call, верните true.
2. Вернуть false.

MemberExpression :

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

Поделись записью