16.1 Scripts

Syntax

Script : ScriptBodyopt ScriptBody : StatementList[~Yield, ~Await, ~Return]

16.1.1 Static Semantics: Early Errors

Script : ScriptBody ScriptBody : StatementList

16.1.2 Static Semantics: IsStrict

Script : ScriptBodyopt
  1. If ScriptBody is present and the Directive Prologue of ScriptBody contains a Use Strict Directive, return true; otherwise, return false.

16.1.3 Runtime Semantics: Evaluation

Script : [empty]
  1. Return NormalCompletion(undefined).

16.1.4 Script Records

A Script Record encapsulates information about a script being evaluated. Each script record contains the fields listed in Table 39.

Table 39: Script Record Fields
Field Name Value Type Meaning
[[Realm]] Realm Record | undefined The realm within which this script was created. undefined if not yet assigned.
[[Environment]] Environment Record | undefined The Environment Record containing the top level bindings for this script. This field is set when the script is instantiated.
[[ECMAScriptCode]] a Parse Node The result of parsing the source text of this script using Script as the goal symbol.
[[HostDefined]] Any, default value is empty. Field reserved for use by host environments that need to associate additional information with a script.

16.1.5 ParseScript ( sourceText, realm, hostDefined )

The abstract operation ParseScript takes arguments sourceText, realm, and hostDefined. It creates a Script Record based upon the result of parsing sourceText as a Script. It performs the following steps when called:

  1. Assert: sourceText is an ECMAScript source text (see clause 11).
  2. Let body be ParseText(sourceText, Script).
  3. If body is a List of errors, return body.
  4. Return Script Record { [[Realm]]: realm, [[Environment]]: undefined, [[ECMAScriptCode]]: body, [[HostDefined]]: hostDefined }.
Note

An implementation may parse script source text and analyse it for Early Error conditions prior to evaluation of ParseScript for that script source text. However, the reporting of any errors must be deferred until the point where this specification actually performs ParseScript upon that source text.

16.1.6 ScriptEvaluation ( scriptRecord )

The abstract operation ScriptEvaluation takes argument scriptRecord. It performs the following steps when called:

  1. Let globalEnv be scriptRecord.[[Realm]].[[GlobalEnv]].
  2. Let scriptContext be a new ECMAScript code execution context.
  3. Set the Function of scriptContext to null.
  4. Set the Realm of scriptContext to scriptRecord.[[Realm]].
  5. Set the ScriptOrModule of scriptContext to scriptRecord.
  6. Set the VariableEnvironment of scriptContext to globalEnv.
  7. Set the LexicalEnvironment of scriptContext to globalEnv.
  8. Suspend the currently running execution context.
  9. Push scriptContext onto the execution context stack; scriptContext is now the running execution context.
  10. Let scriptBody be scriptRecord.[[ECMAScriptCode]].
  11. Let result be GlobalDeclarationInstantiation(scriptBody, globalEnv).
  12. If result.[[Type]] is normal, then
    1. Set result to the result of evaluating scriptBody.
  13. If result.[[Type]] is normal and result.[[Value]] is empty, then
    1. Set result to NormalCompletion(undefined).
  14. Suspend scriptContext and remove it from the execution context stack.
  15. Assert: The execution context stack is not empty.
  16. Resume the context that is now on the top of the execution context stack as the running execution context.
  17. Return Completion(result).

16.1.7 GlobalDeclarationInstantiation ( script, env )

Note 1

When an execution context is established for evaluating scripts, declarations are instantiated in the current global environment. Each global binding declared in the code is instantiated.

The abstract operation GlobalDeclarationInstantiation takes arguments script (a Parse Node for ScriptBody) and env (an Environment Record). script is the ScriptBody for which the execution context is being established. env is the global environment in which bindings are to be created. It performs the following steps when called:

  1. Assert: env is a global Environment Record.
  2. Let lexNames be the LexicallyDeclaredNames of script.
  3. Let varNames be the VarDeclaredNames of script.
  4. For each element name of lexNames, do
    1. If env.HasVarDeclaration(name) is true, throw a SyntaxError exception.
    2. If env.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
    3. Let hasRestrictedGlobal be ? env.HasRestrictedGlobalProperty(name).
    4. If hasRestrictedGlobal is true, throw a SyntaxError exception.
  5. For each element name of varNames, do
    1. If env.HasLexicalDeclaration(name) is true, throw a SyntaxError exception.
  6. Let varDeclarations be the VarScopedDeclarations of script.
  7. Let functionsToInitialize be a new empty List.
  8. Let declaredFunctionNames be a new empty List.
  9. For each element d of varDeclarations, in reverse List order, do
    1. If d is neither a VariableDeclaration nor a ForBinding nor a BindingIdentifier, then
      1. Assert: d is either a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration.
      2. NOTE: If there are multiple function declarations for the same name, the last declaration is used.
      3. Let fn be the sole element of the BoundNames of d.
      4. If fn is not an element of declaredFunctionNames, then
        1. Let fnDefinable be ? env.CanDeclareGlobalFunction(fn).
        2. If fnDefinable is false, throw a TypeError exception.
        3. Append fn to declaredFunctionNames.
        4. Insert d as the first element of functionsToInitialize.
  10. Let declaredVarNames be a new empty List.
  11. For each element d of varDeclarations, do
    1. If d is a VariableDeclaration, a ForBinding, or a BindingIdentifier, then
      1. For each String vn of the BoundNames of d, do
        1. If vn is not an element of declaredFunctionNames, then
          1. Let vnDefinable be ? env.CanDeclareGlobalVar(vn).
          2. If vnDefinable is false, throw a TypeError exception.
          3. If vn is not an element of declaredVarNames, then
            1. Append vn to declaredVarNames.
  12. NOTE: No abnormal terminations occur after this algorithm step if the global object is an ordinary object. However, if the global object is a Proxy exotic object it may exhibit behaviours that cause abnormal terminations in some of the following steps.
  13. NOTE: Annex B.3.3.2 adds additional steps at this point.
  14. Let lexDeclarations be the LexicallyScopedDeclarations of script.
  15. For each element d of lexDeclarations, do
    1. NOTE: Lexically declared names are only instantiated here but not initialized.
    2. For each element dn of the BoundNames of d, do
      1. If IsConstantDeclaration of d is true, then
        1. Perform ? env.CreateImmutableBinding(dn, true).
      2. Else,
        1. Perform ? env.CreateMutableBinding(dn, false).
  16. For each Parse Node f of functionsToInitialize, do
    1. Let fn be the sole element of the BoundNames of f.
    2. Let fo be InstantiateFunctionObject of f with argument env.
    3. Perform ? env.CreateGlobalFunctionBinding(fn, fo, false).
  17. For each String vn of declaredVarNames, do
    1. Perform ? env.CreateGlobalVarBinding(vn, false).
  18. Return NormalCompletion(empty).
Note 2

Early errors specified in 16.1.1 prevent name conflicts between function/var declarations and let/const/class declarations as well as redeclaration of let/const/class bindings for declaration contained within a single Script. However, such conflicts and redeclarations that span more than one Script are detected as runtime errors during GlobalDeclarationInstantiation. If any such errors are detected, no bindings are instantiated for the script. However, if the global object is defined using Proxy exotic objects then the runtime tests for conflicting declarations may be unreliable resulting in an abrupt completion and some global declarations not being instantiated. If this occurs, the code for the Script is not evaluated.

Unlike explicit var or function declarations, properties that are directly created on the global object result in global bindings that may be shadowed by let/const/class declarations.