Контекст выполнения (execution context) — это устройство спецификации, которое используется для отслеживания оценки кода во время выполнения реализацией ECMAScript. В любой момент времени существует не более одного контекста выполнения для каждого агента, который фактически выполняет код. Это называется текущим контекстом выполнения (running execution context) агента. Все ссылки на текущий контекст выполнения в этой спецификации обозначают текущий контекст выполнения окружающего агента (surrounding agent).
Стек контекста выполнения (execution context stack) используется для отслеживания контекстов выполнения. Текущий контекст выполнения всегда является верхним элементом этого стека. Новый контекст выполнения создаётся всякий раз, когда управление передаётся от исполняемого кода, связанного с текущим контекстом выполнения, к исполняемому коду, который не связан с этим контекстом выполнения. Вновь созданный контекст выполнения помещается в стек и становится текущим контекстом выполнения.
Контекст выполнения содержит любое конкретное состояние реализации, необходимое для отслеживания хода выполнения связанного с ним кода. Каждый контекст выполнения имеет как минимум компоненты состояния, перечисленные в таблице 29.
Компонент | Цель | |
---|---|---|
состояние оценки кода | Любое состояние, необходимое для выполнения, приостановки и возобновления оценки кода, связанного с этим контекстом выполнения. | |
Function — Функция | Если этот контекст выполнения оценивает код объекта функции, то значением этого компонента является этот объект функции. Если контекст оценивает код сценария (Script) или модуля (Module), значение равно null. | |
Realm — Область | Запись области, из которой связанный код обращается к ресурсам ECMAScript. | |
ScriptOrModule — Скрипт или Модуль | Запись модуля (Module Record) или запись сценария (Script Record), из которой происходит связанный код. Если нет исходного сценария или модуля, как в случае исходного контекста выполнения, созданного в InitializeHostDefinedRealm, значение равно null. |
Таблица 29: Компоненты состояния для всех контекстов выполнения
Оценка кода текущим контекстом выполнения может быть приостановлена в различных точках, определённых в этой спецификации. Как только текущий контекст выполнения был приостановлен, другой контекст выполнения может стать текущим контекстом выполнения и начать оценку его кода. Через некоторое время приостановленный контекст выполнения может снова стать текущим контекстом выполнения и продолжить оценку своего кода в точке, где он был ранее приостановлен. Переход состояния текущего контекста выполнения между контекстами выполнения обычно происходит по принципу «последний вошёл / первым вышел» (last-in/first-out). Однако некоторые функции ECMAScript требуют не-LIFO переходов текущего контекста выполнения.
Значение компонента области Realm текущего контекста выполнения также называется «текущей записью области» (current Realm Record). Значение компонента функциии Function текущего контекста выполнения также называется «активным функциональным объектом» (active function object).
Контексты выполнения для кода ECMAScript имеют дополнительные компоненты состояния, перечисленные в таблице 30.
Компонент | Цель |
---|---|
LexicalEnvironment (Лексическая среда) | Идентифицирует Запись Среды, используемую для разрешения ссылок на идентификаторы, сделанных кодом в этом контексте выполнения. |
VariableEnvironment (Переменная среда) | Идентифицирует Запись Среды, которая содержит привязки, созданные VariableStatement‘ах в этом контексте выполнения. |
PrivateEnvironment (Частная среда) | Идентифицирует Запись Частной Среды, которая содержит Частные Имена, созданные ClassElement‘ах в ближайшем содержащем классе. null, если нет содержащего класса. |
Таблица 30: Дополнительные компоненты состояния для контекстов выполнения кода ECMAScript
Компоненты LexicalEnvironment и VariableEnvironment контекста выполнения всегда являются Записями Среды.
Контексты выполнения, представляющие оценку Генераторов, имеют дополнительные компоненты состояния, перечисленные в таблице 31.
Компонент | Цель | |
---|---|---|
Generator | Объект генератора, который оценивает этот контекст выполнения. |
Таблица 31: Дополнительные компоненты состояния для контекстов выполнения Генератора
В большинстве случаев только текущий контекст выполнения (вершина стека контекстов выполнения) напрямую управляется алгоритмами в этой спецификации. Следовательно, когда термины «LexicalEnvironment» и «VariableEnvironment» используются без уточнения, они относятся к этим компонентам текущего контекста выполнения.
Контекст выполнения — это чисто механизм спецификации и не обязательно должен соответствовать какому-либо конкретному артефакту реализации ECMAScript. Код ECMAScript не может напрямую обращаться к контексту выполнения или наблюдать за ним.
Абстрактные операции контекста выполнения
- GetActiveScriptOrModule ( )
- ResolveBinding ( name [ , env ] )
- GetThisEnvironment ( )
- ResolveThisBinding ( )
- GetNewTarget ( )
- GetGlobalObject ( )
GetActiveScriptOrModule ( )
Абстрактная операция GetActiveScriptOrModule (Получить активный скрипт или модуль) не принимает аргументов. Она используется для определения запущенного скрипта или модуля в зависимости от текущего контекста выполнения. При вызове она выполняет следующие шаги:
1. Если стек контекста выполнения пуст, вернуть null. 2. Пусть ec будет самым верхним контекстом выполнения в стеке контекстов выполнения, компонент ScriptOrModule которого не равен null. 3. Если такого контекста выполнения не существует, вернуть null. В противном случае верните ScriptOrModule ec.
ResolveBinding ( name [ , env ] )
Абстрактная операция ResolveBinding (Разрешить привязку) принимает аргумент name (Строка) и необязательный аргумент env (Запись Среды или undefined). Она используется для определения привязки name. env можно использовать для явного предоставления Записи Среды, в которой будет выполняться поиск привязки. При вызове она выполняет следующие шаги:
1. Если env отсутствует или если env является undefined, тогда а. Установите env равным LexicalEnvironment текущего контекста выполнения. 2. Утверждено: env - это Запись Среды. 3. Если исходный текст (код), соответствующий синтаксическому производству, которая оценивается, содержится в коде строгого режима, пусть strict будет истинным true; иначе пусть strict будет ложным false. 4. Вернуть ? GetIdentifierReference(env, name, strict).
Результатом ResolveBinding всегда является Ссылочная Запись, в поле [[ReferencedName]] которой указано name.
GetThisEnvironment ( )
Абстрактная операция GetThisEnvironment (Получить среду this) не принимает аргументов. Она находит Запись Среды, которая в настоящее время обеспечивает привязку ключевого слова this. При вызове она выполняет следующие шаги:
1. Пусть env будет LexicalEnvironment текущего контекста выполнения. 2. Повторять, a. Пусть exists будет env.HasThisBinding(). b. Если exists является истиной true, вернуть env. c. Пусть outer будет env.[[OuterEnv]]. d. Утверждено: exists не является null. e. Установите env на outer.
Цикл на шаге 2 всегда завершается, потому что список сред всегда заканчивается глобальной средой, имеющей привязку this.
ResolveThisBinding ( )
Абстрактная операция ResolveThisBinding (Разрешить привязку this) не принимает аргументов. Она определяет привязку ключевого слова this, используя LexicalEnvironment текущего контекста выполнения. При вызове она выполняет следующие шаги:
1. Пусть envRec будет GetThisEnvironment(). 2. Вернуть ? envRec.GetThisBinding().
GetNewTarget ( )
Абстрактная операция GetNewTarget (Получить новую цель) не принимает аргументов. Она определяет значение NewTarget, используя LexicalEnvironment текущего контекста выполнения. При вызове она выполняет следующие шаги:
1. Пусть envRec будет GetThisEnvironment(). 2. Утверждено: envRec имеет поле [[NewTarget]]. 3. Верните envRec.[[NewTarget]].
GetGlobalObject ( )
Абстрактная операция GetGlobalObject (Получить глобальный объект) не принимает аргументов. Она возвращает глобальный объект, используемый текущим контекстом выполнения. При вызове она выполняет следующие шаги:
1. Пусть currentRealm будет текущей Записью Области. 2. Вернуть currentRealm.[[GlobalObject]].
Информационные ссылки
Предыдущий раздел — ECMAScript | Области
Стандарт ECMAScript — Раздел «9.4 Execution Contexts» — https://tc39.es/ecma262/#sec-execution-contexts