Closed erights closed 4 years ago
Also discussed here: https://github.com/Agoric/agoric-sdk/issues/602
Apart from modules and Function()
, we are dealing with three different types of evaluation in JavaScript:
program/script
(available in a script tag) should perform an evaluation in the global lexical scope, something we can't correctly emulate using eval()
of Function()
without parsing the source code. It should not return a completion value.expression
should be single expression because multiple statements can't return multiple completion values, but not specified as such. It makes sense that expressions are evaluated in a new lexical scope, to avoid creating a state accidental between evaluation, but the global object can be affected in sloppy mode.eval()
is a mix of both, plus the capacity to perform direct mode, BUT always executes in a new lexical scope, and always returns a completion value.new Compartment().evaluate()
is proposed normative to:
eval()
The reason are:
Compartment.evaluate()
would create a cross compartment context and make little sense.eval()
function itself isn't going away. It's simpler to specify new Compartment().evaluate()
as a limited form of eval()
, and most likely simpler to implement by the engines.PerformEval( x, callerRealm, true, false)
in the specs (https://tc39.es/ecma262/#sec-performeval).Closing, reasons documented.
Both
realm.evaluate(src, endowments)
andSES.confine(src, endowments)
parse source as a Program and evaluate it to its completion value. Because many JS expressions, when parsed as Programs, will parse as expression-statements, and because the completion value of an expression statement is the value of the expression, we often mistakenly use them to evaluate expressions. We have repeatedly stubbed our toe on expressions that begin with{
orfunction
. These expressions, when parsed as programs, parse as programs that mean something else and have different completion values.Even after introducing the
SES.confineExpr(exprSrc, endowments)
convenience, we still accidentally usedSES.confine
on an inappropriate expression. Suggestion:All new evaluators should come overloaded by explicit suffix clarifying what their start symbol is. Retire
realm.evaluate
andSES.confine
and instead have:realm.evalProgram
realm.evalExpr
SES.confineProgram
SES.confineExpr