19.2.1 eval ( source )
This function is the %eval% intrinsic object.
It performs the following steps when called:
- Return ? PerformEval(source, false, false).
19.2.1.1 PerformEval ( source, strictCaller, direct )
The abstract operation PerformEval takes arguments source (an ECMAScript language value), strictCaller (a Boolean), and direct (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:
- Assert: If direct is false, then strictCaller is also false.
- If source is not a String, return source.
- Let evalRealm be the current Realm Record.
- NOTE: In the case of a direct eval, evalRealm is the realm of both the caller of
eval and of the eval function itself. - Perform ? HostEnsureCanCompileStrings(evalRealm, « », source, direct).
- Let inFunc be false.
- Let inMethod be false.
- Let inDerivedCtor be false.
- Let inClassFieldInitializer be false.
- If direct is true, then
- Let thisEnvRecord be GetThisEnvironment().
- If thisEnvRecord is a Function Environment Record, then
- Let func be thisEnvRecord.[[FunctionObject]].
- Set inFunc to true.
- Set inMethod to thisEnvRecord.HasSuperBinding().
- If func.[[ConstructorKind]] is derived, set inDerivedCtor to true.
- Let classFieldInitializerName be func.[[ClassFieldInitializerName]].
- If classFieldInitializerName is not empty, set inClassFieldInitializer to true.
- Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection:
- Let script be ParseText(source, Script).
- If script is a List of errors, throw a SyntaxError exception.
- If script Contains ScriptBody is false, return undefined.
- Let body be the ScriptBody of script.
- If inFunc is false and body Contains NewTarget, throw a SyntaxError exception.
- If inMethod is false and body Contains SuperProperty, throw a SyntaxError exception.
- If inDerivedCtor is false and body Contains SuperCall, throw a SyntaxError exception.
- If inClassFieldInitializer is true and ContainsArguments of body is true, throw a SyntaxError exception.
- If strictCaller is true, let strictEval be true.
- Else, let strictEval be ScriptIsStrict of script.
- Let runningContext be the running execution context.
- NOTE: If direct is true, runningContext will be the execution context that performed the direct eval. If direct is false, runningContext will be the execution context for the invocation of the
eval function. - If direct is true, then
- Let lexicalEnv be NewDeclarativeEnvironment(runningContext's LexicalEnvironment).
- Let variableEnv be runningContext's VariableEnvironment.
- Let privateEnv be runningContext's PrivateEnvironment.
- Else,
- Let lexicalEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]).
- Let variableEnv be evalRealm.[[GlobalEnv]].
- Let privateEnv be null.
- If strictEval is true, set variableEnv to lexicalEnv.
- If runningContext is not already suspended, suspend runningContext.
- Let evalContext be a new ECMAScript code execution context.
- Set evalContext's Function to null.
- Set evalContext's Realm to evalRealm.
- Set evalContext's ScriptOrModule to runningContext's ScriptOrModule.
- Set evalContext's VariableEnvironment to variableEnv.
- Set evalContext's LexicalEnvironment to lexicalEnv.
- Set evalContext's PrivateEnvironment to privateEnv.
- Push evalContext onto the execution context stack; evalContext is now the running execution context.
- Let result be Completion(EvalDeclarationInstantiation(body, variableEnv, lexicalEnv, privateEnv, strictEval)).
- If result is a normal completion, then
- Set result to Completion(Evaluation of body).
- If result is a normal completion and result.[[Value]] is empty, then
- Set result to NormalCompletion(undefined).
- Suspend evalContext and remove it from the execution context stack.
- Resume the context that is now on the top of the execution context stack as the running execution context.
- Return ? result.
Note
The eval code cannot instantiate variable or function bindings in the variable environment of the calling context that invoked the eval if either the code of the calling context or the eval code is strict mode code. Instead such bindings are instantiated in a new VariableEnvironment that is only accessible to the eval code. Bindings introduced by let, const, or class declarations are always instantiated in a new LexicalEnvironment.
19.2.1.2 HostEnsureCanCompileStrings ( calleeRealm, paramStrings, bodyString, direct )
The host-defined abstract operation HostEnsureCanCompileStrings takes arguments calleeRealm (a Realm Record), paramStrings (a List of Strings), bodyString (a String), and direct (a Boolean) and returns either a normal completion containing unused or a throw completion. It allows host environments to block certain ECMAScript functions which allow developers to interpret and evaluate strings as ECMAScript code.
paramStrings represents the strings that, when using one of the function constructors, will be concatenated together to build the parameters list. bodyString represents the function body or the string passed to an eval call.
direct signifies whether the evaluation is a direct eval.
The default implementation of HostEnsureCanCompileStrings is to return NormalCompletion(unused).
19.2.1.3 EvalDeclarationInstantiation ( body, variableEnv, lexicalEnv, privateEnv, strict )
The abstract operation EvalDeclarationInstantiation takes arguments body (a ScriptBody Parse Node), variableEnv (an Environment Record), lexicalEnv (a Declarative Environment Record), privateEnv (a PrivateEnvironment Record or null), and strict (a Boolean) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:
- Let variableNames be the VarDeclaredNames of body.
- Let variableDeclarations be the VarScopedDeclarations of body.
- If strict is false, then
- If variableEnv is a Global Environment Record, then
- For each element name of variableNames, do
- If HasLexicalDeclaration(variableEnv, name) is true, throw a SyntaxError exception.
- NOTE:
eval will not create a global var declaration that would be shadowed by a global lexical declaration.
- Let thisEnv be lexicalEnv.
- Assert: The following loop will terminate.
- Repeat, while thisEnv and variableEnv are not the same Environment Record,
- If thisEnv is not an Object Environment Record, then
- NOTE: The environment of with statements cannot contain any lexical declaration so it doesn't need to be checked for var/let hoisting conflicts.
- For each element name of variableNames, do
- If ! thisEnv.HasBinding(name) is true, then
- If the host is a web browser or otherwise supports VariableStatements in Catch Blocks, then
- If thisEnv is not the Environment Record for a Catch clause, throw a SyntaxError exception.
- Else,
- Throw a SyntaxError exception.
- NOTE: A direct eval will not hoist var declaration over a like-named lexical declaration.
- Set thisEnv to thisEnv.[[OuterEnv]].
- Let privateIdentifiers be a new empty List.
- Let pointer be privateEnv.
- Repeat, while pointer is not null,
- For each Private Name binding of pointer.[[Names]], do
- If privateIdentifiers does not contain binding.[[Description]], append binding.[[Description]] to privateIdentifiers.
- Set pointer to pointer.[[OuterPrivateEnvironment]].
- If AllPrivateIdentifiersValid of body with argument privateIdentifiers is false, throw a SyntaxError exception.
- Let funcsToInitialize be a new empty List.
- Let declaredFuncNames be a new empty List.
- For each element d of variableDeclarations, in reverse List order, do
- If d is not either a VariableDeclaration, a ForBinding, or a BindingIdentifier, then
- Assert: d is either a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration.
- NOTE: If there are multiple function declarations for the same name, the last declaration is used.
- Let func be the sole element of the BoundNames of d.
- If declaredFuncNames does not contain func, then
- If variableEnv is a Global Environment Record, then
- Let funcDefinable be ? CanDeclareGlobalFunction(variableEnv, func).
- If funcDefinable is false, throw a TypeError exception.
- Append func to declaredFuncNames.
- Insert d as the first element of funcsToInitialize.
- Let declaredVariableNames be a new empty List.
- For each element d of variableDeclarations, do
- If d is either a VariableDeclaration, a ForBinding, or a BindingIdentifier, then
- For each String vn of the BoundNames of d, do
- If declaredFuncNames does not contain vn, then
- If variableEnv is a Global Environment Record, then
- Let vnDefinable be ? CanDeclareGlobalVar(variableEnv, vn).
- If vnDefinable is false, throw a TypeError exception.
- If declaredVariableNames does not contain vn, then
- Append vn to declaredVariableNames.
- If strict is false and the host is a web browser or otherwise supports Block-Level Function Declarations Web Legacy Compatibility Semantics, then
- Let declaredFuncOrVariableNames be the list-concatenation of declaredFuncNames and declaredVariableNames.
- For each FunctionDeclaration f that is directly contained in the StatementList of any Block, CaseClause, or DefaultClause x such that body Contains x is true, do
- Let funcName be the StringValue of the BindingIdentifier of f.
- If replacing the FunctionDeclaration f with a VariableStatement that has funcName as a BindingIdentifier would not produce any Early Errors for body, then
- Let bindingExists be false.
- Set thisEnv to lexicalEnv.
- Assert: The following loop will terminate.
- Repeat, while thisEnv is not variableEnv,
- If thisEnv is not an Object Environment Record, then
- If ! thisEnv.HasBinding(funcName) is true, then
- If the host is a web browser or otherwise supports VariableStatements in Catch Blocks, then
- If thisEnv is not the Environment Record for a Catch clause, set bindingExists to true.
- Else,
- Set bindingExists to true.
- Set thisEnv to thisEnv.[[OuterEnv]].
- If bindingExists is false and variableEnv is a Global Environment Record, then
- If HasLexicalDeclaration(variableEnv, funcName) is false, then
- Let funcDefinable be ? CanDeclareGlobalVar(variableEnv, funcName).
- Else,
- Let funcDefinable be false.
- Else,
- Let funcDefinable be true.
- If bindingExists is false and funcDefinable is true, then
- If declaredFuncOrVariableNames does not contain funcName, then
- If variableEnv is a Global Environment Record, then
- Perform ? CreateGlobalVarBinding(variableEnv, funcName, true).
- Else,
- Set bindingExists to ! variableEnv.HasBinding(funcName).
- If bindingExists is false, then
- Perform ! variableEnv.CreateMutableBinding(funcName, true).
- Perform ! variableEnv.InitializeBinding(funcName, undefined).
- Append funcName to declaredFuncOrVariableNames.
- When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 15.2.6:
- Let gEnv be the running execution context's VariableEnvironment.
- Let bEnv be the running execution context's LexicalEnvironment.
- Let fObj be ! bEnv.GetBindingValue(funcName, false).
- Perform ? gEnv.SetMutableBinding(funcName, fObj, false).
- Return unused.
- NOTE: No abnormal terminations occur after this algorithm step unless variableEnv is a Global Environment Record and the global object is a Proxy exotic object.
- Let lexicalDeclarations be the LexicallyScopedDeclarations of body.
- For each element d of lexicalDeclarations, do
- NOTE: Lexically declared names are only instantiated here but not initialized.
- For each element dn of the BoundNames of d, do
- If IsConstantDeclaration of d is true, then
- Perform ? lexicalEnv.CreateImmutableBinding(dn, true).
- Else,
- Perform ? lexicalEnv.CreateMutableBinding(dn, false).
- For each Parse Node f of funcsToInitialize, do
- Let func be the sole element of the BoundNames of f.
- Let funcObj be InstantiateFunctionObject of f with arguments lexicalEnv and privateEnv.
- If variableEnv is a Global Environment Record, then
- Perform ? CreateGlobalFunctionBinding(variableEnv, func, funcObj, true).
- Else,
- Let bindingExists be ! variableEnv.HasBinding(func).
- If bindingExists is false, then
- NOTE: The following invocation cannot return an abrupt completion because of the validation preceding step 14.
- Perform ! variableEnv.CreateMutableBinding(func, true).
- Perform ! variableEnv.InitializeBinding(func, funcObj).
- Else,
- Perform ! variableEnv.SetMutableBinding(func, funcObj, false).
- For each String vn of declaredVariableNames, do
- If variableEnv is a Global Environment Record, then
- Perform ? CreateGlobalVarBinding(variableEnv, vn, true).
- Else,
- Let bindingExists be ! variableEnv.HasBinding(vn).
- If bindingExists is false, then
- NOTE: The following invocation cannot return an abrupt completion because of the validation preceding step 14.
- Perform ! variableEnv.CreateMutableBinding(vn, true).
- Perform ! variableEnv.InitializeBinding(vn, undefined).
- Return unused.
19.2.5 parseInt ( string, radix )
This function produces an integral Number dictated by interpretation of the contents of string according to the specified radix. Leading white space in string is ignored. If radix coerces to 0 (such as when it is undefined), it is assumed to be 10 except when the number representation begins with "0x" or "0X", in which case it is assumed to be 16. If radix is 16, the number representation may optionally begin with "0x" or "0X".
It is the %parseInt% intrinsic object.
It performs the following steps when called:
- Let inputString be ? ToString(string).
- Let trimmedString be ! TrimString(inputString, start).
- Let sign be 1.
- If trimmedString is not empty and the first code unit of trimmedString is the code unit 0x002D (HYPHEN-MINUS), set sign to -1.
- If trimmedString is not empty and the first code unit of trimmedString is either the code unit 0x002B (PLUS SIGN) or the code unit 0x002D (HYPHEN-MINUS), set trimmedString to the substring of trimmedString from index 1.
- Let radixMV be ℝ(? ToInt32(radix)).
- Let stripPrefix be true.
- If radixMV ≠ 0, then
- If radixMV < 2 or radixMV > 36, return NaN.
- If radixMV ≠ 16, set stripPrefix to false.
- Else,
- Set radixMV to 10.
- If stripPrefix is true, then
- If the length of trimmedString ≥ 2 and the first two code units of trimmedString are either "0x" or "0X", then
- Set trimmedString to the substring of trimmedString from index 2.
- Set radixMV to 16.
- If trimmedString contains a code unit that is not a radix-radixMV digit, let end be the index within trimmedString of the first such code unit; else let end be the length of trimmedString.
- Let numberString be the substring of trimmedString from 0 to end.
- If numberString is empty, return NaN.
- Let mathInt be the integer value that is represented by numberString in radix-radixMV notation, using the letters A through Z and a through z for digits with values 10 through 35. (However, if radixMV = 10 and numberString contains more than 20 significant digits, every significant digit after the 20th may be replaced by a 0 digit, at the option of the implementation; and if radixMV is not one of 2, 4, 8, 10, 16, or 32, then mathInt may be an implementation-approximated integer representing the integer value denoted by numberString in radix-radixMV notation.)
- If mathInt = 0, then
- If sign = -1, return -0𝔽.
- Return +0𝔽.
- Return 𝔽(sign × mathInt).
Note
This function may interpret only a leading portion of string as an integer value; it ignores any code units that cannot be interpreted as part of the notation of an integer, and no indication is given that any such code units were ignored.
19.2.6 URI Handling Functions
Uniform Resource Identifiers, or URIs, are Strings that identify resources (e.g. web pages or files) and transport protocols by which to access them (e.g. HTTP or FTP) on the Internet. The ECMAScript language itself does not provide any support for using URIs except for functions that encode and decode URIs as described in this section. encodeURI and decodeURI are intended to work with complete URIs; they assume that any reserved characters are intended to have special meaning (e.g., as delimiters) and so are not encoded. encodeURIComponent and decodeURIComponent are intended to work with the individual components of a URI; they assume that any reserved characters represent text and must be encoded to avoid special meaning when the component is part of a complete URI.
Note 1
The set of reserved characters is based upon RFC 2396 and does not reflect changes introduced by the more recent RFC 3986.
Note 2
Many implementations of ECMAScript provide additional functions and methods that manipulate web pages; these functions are beyond the scope of this standard.
19.2.6.1 decodeURI ( encodedURI )
This function computes a new version of a URI in which each escape sequence and UTF-8 encoding of the sort that might be introduced by the encodeURI function is replaced with the UTF-16 encoding of the code point that it represents. Escape sequences that could not have been introduced by encodeURI are not replaced.
It is the %decodeURI% intrinsic object.
It performs the following steps when called:
- Let uriString be ? ToString(encodedURI).
- Let preserveEscapeSet be ";/?:@&=+$,#".
- Return ? Decode(uriString, preserveEscapeSet).
19.2.6.2 decodeURIComponent ( encodedURIComponent )
This function computes a new version of a URI in which each escape sequence and UTF-8 encoding of the sort that might be introduced by the encodeURIComponent function is replaced with the UTF-16 encoding of the code point that it represents.
It is the %decodeURIComponent% intrinsic object.
It performs the following steps when called:
- Let componentString be ? ToString(encodedURIComponent).
- Let preserveEscapeSet be the empty String.
- Return ? Decode(componentString, preserveEscapeSet).
19.2.6.3 encodeURI ( uri )
This function computes a new version of a UTF-16 encoded (6.1.4) URI in which each instance of certain code points is replaced by one, two, three, or four escape sequences representing the UTF-8 encoding of the code point.
It is the %encodeURI% intrinsic object.
It performs the following steps when called:
- Let uriString be ? ToString(uri).
- Let extraUnescaped be ";/?:@&=+$,#".
- Return ? Encode(uriString, extraUnescaped).
19.2.6.4 encodeURIComponent ( uriComponent )
This function computes a new version of a UTF-16 encoded (6.1.4) URI in which each instance of certain code points is replaced by one, two, three, or four escape sequences representing the UTF-8 encoding of the code point.
It is the %encodeURIComponent% intrinsic object.
It performs the following steps when called:
- Let componentString be ? ToString(uriComponent).
- Let extraUnescaped be the empty String.
- Return ? Encode(componentString, extraUnescaped).
19.2.6.5 Encode ( string, extraUnescaped )
The abstract operation Encode takes arguments string (a String) and extraUnescaped (a String) and returns either a normal completion containing a String or a throw completion. It performs URI encoding and escaping, interpreting string as a sequence of UTF-16 encoded code points as described in 6.1.4. If a character is identified as unreserved in RFC 2396 or appears in extraUnescaped, it is not escaped. It performs the following steps when called:
- Let length be the length of string.
- Let result be the empty String.
- Let alwaysUnescaped be the string-concatenation of the ASCII word characters and "-.!~*'()".
- Let unescapedSet be the string-concatenation of alwaysUnescaped and extraUnescaped.
- Let k be 0.
- Repeat, while k < length,
- Let codeUnit be the code unit at index k within string.
- If unescapedSet contains codeUnit, then
- Set k to k + 1.
- Set result to the string-concatenation of result and codeUnit.
- Else,
- Let codePoint be CodePointAt(string, k).
- If codePoint.[[IsUnpairedSurrogate]] is true, throw a URIError exception.
- Set k to k + codePoint.[[CodeUnitCount]].
- Let octets be the List of octets resulting by applying the UTF-8 transformation to codePoint.[[CodePoint]].
- For each element octet of octets, do
- Let hex be the String representation of octet, formatted as an uppercase hexadecimal number.
- Set result to the string-concatenation of result, "%", and StringPad(hex, 2, "0", start).
- Return result.
Note
Because percent-encoding is used to represent individual octets, a single code point may be expressed as multiple consecutive escape sequences (one for each of its 8-bit UTF-8 code units).
19.2.6.6 Decode ( string, preserveEscapeSet )
The abstract operation Decode takes arguments string (a String) and preserveEscapeSet (a String) and returns either a normal completion containing a String or a throw completion. It performs URI unescaping and decoding, preserving any escape sequences that correspond to Basic Latin characters in preserveEscapeSet. It performs the following steps when called:
- Let length be the length of string.
- Let result be the empty String.
- Let k be 0.
- Repeat, while k < length,
- Let codeUnit be the code unit at index k within string.
- Let segment be codeUnit.
- If codeUnit is the code unit 0x0025 (PERCENT SIGN), then
- If k + 3 > length, throw a URIError exception.
- Let escape be the substring of string from k to k + 3.
- Let firstOctet be ParseHexOctet(string, k + 1).
- If firstOctet is not an integer, throw a URIError exception.
- Set k to k + 2.
- Let n be the number of leading 1 bits in firstOctet.
- If n = 0, then
- Let asciiChar be the code unit whose numeric value is firstOctet.
- If preserveEscapeSet contains asciiChar, set segment to escape; else set segment to asciiChar.
- Else,
- If n = 1 or n > 4, throw a URIError exception.
- Let octets be « firstOctet ».
- Let j be 1.
- Repeat, while j < n,
- Set k to k + 1.
- If k + 3 > length, throw a URIError exception.
- If the code unit at index k within string is not the code unit 0x0025 (PERCENT SIGN), throw a URIError exception.
- Let continuationByte be ParseHexOctet(string, k + 1).
- If continuationByte is not an integer, throw a URIError exception.
- Append continuationByte to octets.
- Set k to k + 2.
- Set j to j + 1.
- Assert: The length of octets is n.
- If octets does not contain a valid UTF-8 encoding of a Unicode code point, throw a URIError exception.
- Let codePoint be the code point obtained by applying the UTF-8 transformation to octets, that is, from a List of octets into a 21-bit value.
- Set segment to UTF16EncodeCodePoint(codePoint).
- Set result to the string-concatenation of result and segment.
- Set k to k + 1.
- Return result.
Note
RFC 3629 prohibits the decoding of invalid UTF-8 octet sequences. For example, the invalid sequence 0xC0 0x80 must not decode into the code unit 0x0000. Implementations of the Decode algorithm are required to throw a URIError when encountering such invalid sequences.
19.2.6.7 ParseHexOctet ( string, position )
The abstract operation ParseHexOctet takes arguments string (a String) and position (a non-negative integer) and returns either a non-negative integer or a non-empty List of SyntaxError objects. It parses a sequence of two hexadecimal characters at the specified position in string into an unsigned 8-bit integer. It performs the following steps when called:
- Let length be the length of string.
- Assert: position + 2 ≤ length.
- Let hexDigits be the substring of string from position to position + 2.
- Let parseResult be ParseText(hexDigits, HexDigits[~Sep]).
- If parseResult is not a Parse Node, return parseResult.
- Let n be the MV of parseResult.
- Assert: n is in the inclusive interval from 0 to 255.
- Return n.