Stage 0 Draft / May 29, 2019

Proposal Evalable

Relaxes the "Type(x) is string" requirement for inputs to eval to enable restricting dynamic code loading to values that have been attested to previously.

1eval ( 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, calleeRealm, false, false).

1.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. If Type(x) is not String IsCodeLike(x) is not true, return x.
  3. Set x to ! ToString(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).

1.2Runtime Semantics: IsCodeLike ( x )

The abstract operation IsCodeLike with argument x performs steps TBD (see options below).

Option 1 - Internal slot [[CodeLike]]

Use an internal slot to distinguish code-like objects.

2eval ( x )

2.1Runtime Semantics: IsCodeLike ( x )

The abstract operation IsCodeLike with argument x performs the following steps:

  1. If Type(x) is String, return true.
  2. If Type(x) is Object, then
    1. If x has a [[CodeLike]] internal slot, then return true.
  3. Return false.

Option 2 - Well known symbol

Use a new well-known symbol to distinguish code-like objects.

3Well-Known Symbols

Table 1: Well-known Symbols
Specification Name [[Description]] Value and Purpose
@@evalable "Symbol.evalable" Boolean property that indicates whether the object may be interpreted as code by eval.

4eval ( x )

4.1Runtime Semantics: IsCodeLike ( x )

The abstract operation IsCodeLike with argument x performs the following steps:

  1. If Type(x) is String, return true.
  2. If Type(x) is Object, then
    1. Let evalable be ? Get(x, @@evalable).
    2. Return ToBoolean(evalable).
  3. Return false.

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.