19.2.1 eval ( x )
This function is the %eval% intrinsic object.
It performs the following steps when called:
- Return ?
PerformEval
(x,
false
,
false
).
19.2.1.1 PerformEval ( x, strictCaller, direct )
The abstract operation PerformEval takes arguments x (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 x
is not a String
, return x.
- 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, « », x, direct).
- Let inFunction be
false
.
- Let inMethod be
false
.
- Let inDerivedConstructor be
false
.
- Let inClassFieldInitializer be
false
.
- If direct is
true
, then
- Let thisEnvRec be
GetThisEnvironment
().
- If thisEnvRec is a
Function Environment Record
, then
- Let F be thisEnvRec.[[FunctionObject]].
- Set inFunction to
true
.
- Set inMethod to thisEnvRec.HasSuperBinding().
- If F.[[ConstructorKind]] is
derived
, set inDerivedConstructor to
true
.
- Let classFieldInitializerName be F.[[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
(x,
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 inFunction is
false
and body
Contains
NewTarget
, throw a
SyntaxError
exception.
- If inMethod is
false
and body
Contains
SuperProperty
, throw a
SyntaxError
exception.
- If inDerivedConstructor 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 lexEnv be
NewDeclarativeEnvironment
(runningContext's LexicalEnvironment).
- Let varEnv be runningContext's VariableEnvironment.
- Let privateEnv be runningContext's PrivateEnvironment.
- Else,
- Let lexEnv be
NewDeclarativeEnvironment
(evalRealm.[[GlobalEnv]]).
- Let varEnv be evalRealm.[[GlobalEnv]].
- Let privateEnv be
null
.
- If strictEval is
true
, set varEnv to lexEnv.
- 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 varEnv.
- Set evalContext's LexicalEnvironment to lexEnv.
- 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, varEnv, lexEnv, 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, parameterStrings, bodyString, direct )
The
host-defined
abstract operation HostEnsureCanCompileStrings takes arguments calleeRealm (a
Realm Record
), parameterStrings (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.
parameterStrings 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, varEnv, lexEnv, privateEnv, strict )
The abstract operation EvalDeclarationInstantiation takes arguments body (a
ScriptBody
Parse Node
), varEnv (an
Environment Record
), lexEnv (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 varNames be the
VarDeclaredNames
of body.
- Let varDeclarations be the
VarScopedDeclarations
of body.
- If strict is
false
, then
- If varEnv is a
Global Environment Record
, then
- For each element name of varNames, do
- If varEnv.HasLexicalDeclaration(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 lexEnv.
-
Assert
: The following loop will terminate.
- Repeat, while thisEnv and varEnv 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 varNames, do
- If ! thisEnv.HasBinding(name) is
true
, then
- Throw a
SyntaxError
exception.
- NOTE: Annex
B.3.4
defines alternate semantics for the above step.
- 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 functionsToInitialize be a new empty
List
.
- Let declaredFunctionNames be a new empty
List
.
- For each element d of varDeclarations, 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 fn be the sole element of the
BoundNames
of d.
- If declaredFunctionNames does not contain fn, then
- If varEnv is a
Global Environment Record
, then
- Let fnDefinable be ? varEnv.CanDeclareGlobalFunction(fn).
- If fnDefinable is
false
, throw a
TypeError
exception.
- Append fn to declaredFunctionNames.
- Insert d as the first element of functionsToInitialize.
- Let declaredVarNames be a new empty
List
.
- For each element d of varDeclarations, do
- If d is either a
VariableDeclaration
, a
ForBinding
, or a
BindingIdentifier
, then
- For each String vn of the
BoundNames
of d, do
- If declaredFunctionNames does not contain vn, then
- If varEnv is a
Global Environment Record
, then
- Let vnDefinable be ? varEnv.CanDeclareGlobalVar(vn).
- If vnDefinable is
false
, throw a
TypeError
exception.
- If declaredVarNames does not contain vn, then
- Append vn to declaredVarNames.
- NOTE: Annex
B.3.2.3
adds additional steps at this point.
- NOTE: No abnormal terminations occur after this algorithm step unless varEnv is a
Global Environment Record
and the
global object
is a
Proxy exotic object
.
- Let lexDeclarations be the
LexicallyScopedDeclarations
of body.
- For each element d of lexDeclarations, 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 ? lexEnv.CreateImmutableBinding(dn,
true
).
- Else,
- Perform ? lexEnv.CreateMutableBinding(dn,
false
).
- For each
Parse Node
f of functionsToInitialize, do
- Let fn be the sole element of the
BoundNames
of f.
- Let fo be
InstantiateFunctionObject
of f with arguments lexEnv and privateEnv.
- If varEnv is a
Global Environment Record
, then
- Perform ? varEnv.CreateGlobalFunctionBinding(fn, fo,
true
).
- Else,
- Let bindingExists be ! varEnv.HasBinding(fn).
- If bindingExists is
false
, then
- NOTE: The following invocation cannot return an
abrupt completion
because of the validation preceding step
14
.
- Perform ! varEnv.CreateMutableBinding(fn,
true
).
- Perform ! varEnv.InitializeBinding(fn, fo).
- Else,
- Perform ! varEnv.SetMutableBinding(fn, fo,
false
).
- For each String vn of declaredVarNames, do
- If varEnv is a
Global Environment Record
, then
- Perform ? varEnv.CreateGlobalVarBinding(vn,
true
).
- Else,
- Let bindingExists be ! varEnv.HasBinding(vn).
- If bindingExists is
false
, then
- NOTE: The following invocation cannot return an
abrupt completion
because of the validation preceding step
14
.
- Perform ! varEnv.CreateMutableBinding(vn,
true
).
- Perform ! varEnv.InitializeBinding(vn,
undefined
).
- Return
unused
.
Note
An alternative version of this algorithm is described in
B.3.4
.
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 S be !
TrimString
(inputString,
start
).
- Let sign be 1.
- If S is not empty and the first code unit of S is the code unit 0x002D (HYPHEN-MINUS), set sign to -1.
- If S is not empty and the first code unit of S is either the code unit 0x002B (PLUS SIGN) or the code unit 0x002D (HYPHEN-MINUS), set S to the
substring
of S from index 1.
- Let R be
ℝ
(?
ToInt32
(radix)).
- Let stripPrefix be
true
.
- If R ≠ 0, then
- If R < 2 or R > 36, return
NaN
.
- If R ≠ 16, set stripPrefix to
false
.
- Else,
- Set R to 10.
- If stripPrefix is
true
, then
- If the length of S is at least 2 and the first two code units of S are either
"0x"
or
"0X"
, then
- Set S to the
substring
of S from index 2.
- Set R to 16.
- If S contains a code unit that is not a radix-R digit, let end be the index within S of the first such code unit; otherwise, let end be the length of S.
- Let Z be the
substring
of S from 0 to end.
- If Z is empty, return
NaN
.
- Let mathInt be the
integer
value that is represented by Z in radix-R notation, using the letters A through Z and a through z for digits with values 10 through 35. (However, if R = 10 and Z 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 R 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 Z in radix-R 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 len be the length of string.
- Let R 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 < len,
- Let C be the code unit at index k within string.
- If unescapedSet contains C, then
- Set k to k + 1.
- Set R to the
string-concatenation
of R and C.
- Else,
- Let cp be
CodePointAt
(string, k).
- If cp.[[IsUnpairedSurrogate]] is
true
, throw a
URIError
exception.
- Set k to k + cp.[[CodeUnitCount]].
- Let Octets be the
List
of octets resulting by applying the UTF-8 transformation to cp.[[CodePoint]].
- For each element octet of Octets, do
- Let hex be the String representation of octet, formatted as an uppercase hexadecimal number.
- Set R to the
string-concatenation
of R,
"%"
, and
StringPad
(hex, 2,
"0"
,
start
).
- Return R.
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 len be the length of string.
- Let R be the empty String.
- Let k be 0.
- Repeat, while k < len,
- Let C be the code unit at index k within string.
- Let S be C.
- If C is the code unit 0x0025 (PERCENT SIGN), then
- If k + 3 > len, throw a
URIError
exception.
- Let escape be the
substring
of string from k to k + 3.
- Let B be
ParseHexOctet
(string, k + 1).
- If B is not an
integer
, throw a
URIError
exception.
- Set k to k + 2.
- Let n be the number of leading 1 bits in B.
- If n = 0, then
- Let asciiChar be the code unit whose numeric value is B.
- If preserveEscapeSet contains asciiChar, set S to escape. Otherwise, set S to asciiChar.
- Else,
- If n = 1 or n > 4, throw a
URIError
exception.
- Let Octets be « B ».
- Let j be 1.
- Repeat, while j < n,
- Set k to k + 1.
- If k + 3 > len, 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 V 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 S to
UTF16EncodeCodePoint
(V).
- Set R to the
string-concatenation
of R and S.
- Set k to k + 1.
- Return R.
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 len be the length of string.
-
Assert
: position + 2 ≤ len.
- 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.