Stage -1 Draft / April 2, 2019

TC39/ecma262 issue

Option 1: Consolidate Host Callouts into PerformEval

1Runtime Semantics: Evaluation

CallExpression:CoverCallExpressionAndAsyncArrowHead
  1. Let expr be CoveredCallExpression of CoverCallExpressionAndAsyncArrowHead.
  2. Let memberExpr be the MemberExpression of expr.
  3. Let arguments be the Arguments of expr.
  4. Let ref be the result of evaluating memberExpr.
  5. Let func be ? GetValue(ref).
  6. If Type(ref) is Reference and IsPropertyReference(ref) is false and GetReferencedName(ref) is "eval", then
    1. If SameValue(func, %eval%) is true, then
      1. Let argList be ? ArgumentListEvaluation of arguments.
      2. If argList has no elements, return undefined.
      3. Let evalText be the first element of argList.
      4. If the source code matching this CallExpression is strict mode code, let strictCaller be true. Otherwise let strictCaller be false.
      5. Let evalRealm be the current Realm Record.
      6. Perform ? HostEnsureCanCompileStrings(evalRealm, evalRealm).
      7. Return ? PerformEval(evalText, evalRealm, evalRealm, strictCaller, true).
  7. Let thisCall be this CallExpression.
  8. Let tailCall be IsInTailPosition(thisCall).
  9. Return ? EvaluateCall(func, ref, arguments, tailCall).

A CallExpression evaluation that executes step 6.a.vii is a direct eval.

2eval ( x )

The eval function is the %eval% intrinsic object. When the eval function is called with one argument x, the following steps are taken:

  1. Assert: The execution context stack has at least two elements.
  2. Let callerContext be the second to top element of the execution context stack.
  3. Let callerRealm be callerContext's Realm.
  4. Let calleeRealm be the current Realm Record.
  5. Perform ? HostEnsureCanCompileStrings(callerRealm, calleeRealm).
  6. Return ? PerformEval(x, callerRealm, calleeRealm, false, false).

2.1Runtime Semantics: PerformEval ( x, evalRealm, callerRealm, calleeRealm, strictCaller, direct )

The abstract operation PerformEval with arguments x, evalRealm, callerRealm, calleeRealm, strictCaller, and direct performs the following steps:

  1. Assert: If direct is false, then strictCaller is also false.
  2. If Type(x) is not String, return x.
  3. Perform ? HostEnsureCanCompileStrings(callerRealm, calleeRealm).
  4. Let evalRealm be calleeRealm.
  5. Let thisEnvRec be ! GetThisEnvironment().
  6. If thisEnvRec is a function Environment Record, then
    1. Let F be thisEnvRec.[[FunctionObject]].
    2. Let inFunction be true.
    3. Let inMethod be thisEnvRec.HasSuperBinding().
    4. If F.[[ConstructorKind]] is "derived", let inDerivedConstructor be true; otherwise, let inDerivedConstructor be false.
  7. Else,
    1. Let inFunction be false.
    2. Let inMethod be false.
    3. Let inDerivedConstructor be false.
  8. Let script be the ECMAScript code that is the result of parsing x, interpreted as UTF-16 encoded Unicode text as described in 6.1.4, for the goal symbol Script. If inFunction is false, additional early error rules from 18.2.1.1.1 are applied. If inMethod is false, additional early error rules from 18.2.1.1.2 are applied. If inDerivedConstructor is false, additional early error rules from 18.2.1.1.3 are applied. If the parse fails, throw a SyntaxError exception. If any early errors are detected, throw a SyntaxError or a ReferenceError exception, depending on the type of the error (but see also clause 16). Parsing and early error detection may be interweaved in an implementation-dependent manner.
  9. If script Contains ScriptBody is false, return undefined.
  10. Let body be the ScriptBody of script.
  11. If strictCaller is true, let strictEval be true.
  12. Else, let strictEval be IsStrict of script.
  13. Let ctx be the running execution context.
  14. NOTE: If direct is true, ctx will be the execution context that performed the direct eval. If direct is false, ctx will be the execution context for the invocation of the eval function.
  15. If direct is true, then
    1. Let lexEnv be NewDeclarativeEnvironment(ctx's LexicalEnvironment).
    2. Let varEnv be ctx's VariableEnvironment.
  16. Else,
    1. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]).
    2. Let varEnv be evalRealm.[[GlobalEnv]].
  17. If strictEval is true, set varEnv to lexEnv.
  18. If ctx is not already suspended, suspend ctx.
  19. Let evalCxt be a new ECMAScript code execution context.
  20. Set the evalCxt's Function to null.
  21. Set the evalCxt's Realm to evalRealm.
  22. Set the evalCxt's ScriptOrModule to ctx's ScriptOrModule.
  23. Set the evalCxt's VariableEnvironment to varEnv.
  24. Set the evalCxt's LexicalEnvironment to lexEnv.
  25. Push evalCxt on to the execution context stack; evalCxt is now the running execution context.
  26. Let result be EvalDeclarationInstantiation(body, varEnv, lexEnv, strictEval).
  27. If result.[[Type]] is normal, then
    1. Set result to the result of evaluating body.
  28. If result.[[Type]] is normal and result.[[Value]] is empty, then
    1. Set result to NormalCompletion(undefined).
  29. Suspend evalCxt and remove it from the execution context stack.
  30. Resume the context that is now on the top of the execution context stack as the running execution context.
  31. Return Completion(result).

Option 2: Hoist the argument type check out of PerformEval

3Runtime Semantics: Evaluation

CallExpression:CoverCallExpressionAndAsyncArrowHead
  1. Let expr be CoveredCallExpression of CoverCallExpressionAndAsyncArrowHead.
  2. Let memberExpr be the MemberExpression of expr.
  3. Let arguments be the Arguments of expr.
  4. Let ref be the result of evaluating memberExpr.
  5. Let func be ? GetValue(ref).
  6. If Type(ref) is Reference and IsPropertyReference(ref) is false and GetReferencedName(ref) is "eval", then
    1. If SameValue(func, %eval%) is true, then
      1. Let argList be ? ArgumentListEvaluation of arguments.
      2. If argList has no elements, return undefined.
      3. Let evalText be the first element of argList.
      4. If Type(evalText) is not String, return evalText.
      5. If the source code matching this CallExpression is strict mode code, let strictCaller be true. Otherwise let strictCaller be false.
      6. Let evalRealm be the current Realm Record.
      7. Perform ? HostEnsureCanCompileStrings(evalRealm, evalRealm).
      8. Return ? PerformEval(evalText, evalRealm, strictCaller, true).
  7. Let thisCall be this CallExpression.
  8. Let tailCall be IsInTailPosition(thisCall).
  9. Return ? EvaluateCall(func, ref, arguments, tailCall).

A CallExpression evaluation that executes step 6.a.vii is a direct eval.

4eval ( x )

The eval function is the %eval% intrinsic object. When the eval function is called with one argument x, the following steps are taken:

  1. Assert: The execution context stack has at least two elements.
  2. If Type(x) is not String, return x.
  3. Let callerContext be the second to top element of the execution context stack.
  4. Let callerRealm be callerContext's Realm.
  5. Let calleeRealm be the current Realm Record.
  6. Perform ? HostEnsureCanCompileStrings(callerRealm, calleeRealm).
  7. Return ? PerformEval(x, calleeRealm, false, false).

4.1Runtime Semantics: PerformEval ( x, evalRealm, strictCaller, direct )

The abstract operation PerformEval with arguments x, evalRealm, strictCaller, and direct performs the following steps:

  1. Assert: If direct is false, then strictCaller is also false.
  2. Assert: Type(x) is String.
  3. If Type(x) is not String, return x.
  4. Let thisEnvRec be ! GetThisEnvironment().
  5. If thisEnvRec is a function Environment Record, then
    1. Let F be thisEnvRec.[[FunctionObject]].
    2. Let inFunction be true.
    3. Let inMethod be thisEnvRec.HasSuperBinding().
    4. If F.[[ConstructorKind]] is "derived", let inDerivedConstructor be true; otherwise, let inDerivedConstructor be false.
  6. Else,
    1. Let inFunction be false.
    2. Let inMethod be false.
    3. Let inDerivedConstructor be false.
  7. Let script be the ECMAScript code that is the result of parsing x, interpreted as UTF-16 encoded Unicode text as described in 6.1.4, for the goal symbol Script. If inFunction is false, additional early error rules from 18.2.1.1.1 are applied. If inMethod is false, additional early error rules from 18.2.1.1.2 are applied. If inDerivedConstructor is false, additional early error rules from 18.2.1.1.3 are applied. If the parse fails, throw a SyntaxError exception. If any early errors are detected, throw a SyntaxError or a ReferenceError exception, depending on the type of the error (but see also clause 16). Parsing and early error detection may be interweaved in an implementation-dependent manner.
  8. If script Contains ScriptBody is false, return undefined.
  9. Let body be the ScriptBody of script.
  10. If strictCaller is true, let strictEval be true.
  11. Else, let strictEval be IsStrict of script.
  12. Let ctx be the running execution context.
  13. NOTE: If direct is true, ctx will be the execution context that performed the direct eval. If direct is false, ctx will be the execution context for the invocation of the eval function.
  14. If direct is true, then
    1. Let lexEnv be NewDeclarativeEnvironment(ctx's LexicalEnvironment).
    2. Let varEnv be ctx's VariableEnvironment.
  15. Else,
    1. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]).
    2. Let varEnv be evalRealm.[[GlobalEnv]].
  16. If strictEval is true, set varEnv to lexEnv.
  17. If ctx is not already suspended, suspend ctx.
  18. Let evalCxt be a new ECMAScript code execution context.
  19. Set the evalCxt's Function to null.
  20. Set the evalCxt's Realm to evalRealm.
  21. Set the evalCxt's ScriptOrModule to ctx's ScriptOrModule.
  22. Set the evalCxt's VariableEnvironment to varEnv.
  23. Set the evalCxt's LexicalEnvironment to lexEnv.
  24. Push evalCxt on to the execution context stack; evalCxt is now the running execution context.
  25. Let result be EvalDeclarationInstantiation(body, varEnv, lexEnv, strictEval).
  26. If result.[[Type]] is normal, then
    1. Set result to the result of evaluating body.
  27. If result.[[Type]] is normal and result.[[Value]] is empty, then
    1. Set result to NormalCompletion(undefined).
  28. Suspend evalCxt and remove it from the execution context stack.
  29. Resume the context that is now on the top of the execution context stack as the running execution context.
  30. Return Completion(result).

ACopyright & Software License

Copyright Notice

© 2019 Mike Samuel

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.