eval operator with != 1 arguments
A bit off topic: FF had a second argument to eval which enabled a form of sandboxing but was removed due to security issues - peeking into closures: bugzilla.mozilla.org/show_bug.cgi?id=442333
With ES5 strict mode and the ability to freeze objects could this eval be 'resurrected' (once again) to meet the sandboxing usecase (see comment #20 in the bug report). This revised eval could be the basis for a module system. The second argument acts as a dependency injection container for modules. // ES5 strict mode only // second context arg must be frozen const mymod = eval("...", myglobal);
Maybe the second arg should be a string which itself is eval'ed in a clean context to return a frozen global object (or a least one where the primordials are frozen). Thus the second arg could not be used to peek into existing objects which are hiding private vars via closures. Modules using this eval would exist in a more restrictive world than even ES5 strict mode - but maybe that is a good thing.
On Jan 14, 2010, at 6:27 PM, Mike Samuel wrote:
Any thoughts on whether (eval(a, b)) should be an invocation of the eval operator?
What do current browsers do? It's an eval operator in Mozilla-based
browsers. Seems to be eval (dynamic scope, not global scope) in Safari
too.
What would be the benefit of changing a future edition to make such an
eval "indirect"?
2010/1/15 Brendan Eich <brendan at mozilla.com>:
On Jan 14, 2010, at 6:27 PM, Mike Samuel wrote:
Any thoughts on whether (eval(a, b)) should be an invocation of the eval operator?
What do current browsers do? It's an eval operator in Mozilla-based browsers. Seems to be eval (dynamic scope, not global scope) in Safari too.
What would be the benefit of changing a future edition to make such an eval "indirect"?
I am not advocating changing eval in a future edition.
What I found confusing was that the previous section started with "When the eval function is called with one argument x, the following steps are taken:" and whether that was assumed by the following section.
But somebody here read 15.1.2.1 and concluded that eval with other than one argument was the function. I concluded otherwise. I still don't know what the answer is?
On Jan 15, 2010, at 5:49 PM, Mike Samuel wrote:
2010/1/15 Brendan Eich <brendan at mozilla.com>:
On Jan 14, 2010, at 6:27 PM, Mike Samuel wrote:
Any thoughts on whether (eval(a, b)) should be an invocation of the eval operator?
What do current browsers do? It's an eval operator in Mozilla-based browsers. Seems to be eval (dynamic scope, not global scope) in
Safari too.What would be the benefit of changing a future edition to make such
an eval "indirect"?I am not advocating changing eval in a future edition.
What I found confusing was that the previous section started with "When the eval function is called with one argument x, the following steps are taken:" and whether that was assumed by the following section.
But somebody here read 15.1.2.1 and concluded that eval with other than one argument was the function. I concluded otherwise. I still don't know what the answer is?
"15.1.2.1.1 Direct Call to Eval" does not care about number of actual
arguments, only about the two conditions:
"The Reference that is the result of evaluating the MemberExpression
in the CallExpression has an environment record as its base value and
its reference name is "eval".
The result of calling the abstract operation GetValue with that
Reference as the argument is the standard built-in function defined in
15.1.2.1."
So ES5 says eval(s, x) is a direct call.
"When the eval function is called with one argument x, the following
steps are taken" is misworded -- it wants to introduce the
metavariable x but it overspecifies for the case of exactly one
argument. In fact eval() returns undefined per the specified
semantics, and so does eval(undefined, {}). And at least Firefox and
Safari eval(s, {}) where s is a string as a direct eval call.
On Fri, Jan 15, 2010 at 7:11 PM, Brendan Eich <brendan at mozilla.com> wrote:
On Jan 15, 2010, at 5:49 PM, Mike Samuel wrote:
2010/1/15 Brendan Eich <brendan at mozilla.com>:
On Jan 14, 2010, at 6:27 PM, Mike Samuel wrote:
Any thoughts on whether (eval(a, b)) should be an invocation of the eval operator?
What do current browsers do? It's an eval operator in Mozilla-based browsers. Seems to be eval (dynamic scope, not global scope) in Safari too.
What would be the benefit of changing a future edition to make such an eval "indirect"?
I am not advocating changing eval in a future edition.
What I found confusing was that the previous section started with "When the eval function is called with one argument x, the following steps are taken:" and whether that was assumed by the following section.
But somebody here read 15.1.2.1 and concluded that eval with other than one argument was the function.
"Somebody here" was Tom and I, with the misunderstanding probably being by me.
I concluded otherwise. I still don't know what the answer is?
"15.1.2.1.1 Direct Call to Eval" does not care about number of actual arguments, only about the two conditions:
"The Reference that is the result of evaluating the MemberExpression in the CallExpression has an environment record as its base value and its reference name is "eval".
The result of calling the abstract operation GetValue with that Reference as the argument is the standard built-in function defined in 15.1.2.1."
So ES5 says eval(s, x) is a direct call.
"When the eval function is called with one argument x, the following steps are taken" is misworded -- it wants to introduce the metavariable x but it overspecifies for the case of exactly one argument. In fact eval() returns undefined per the specified semantics, and so does eval(undefined, {}). And at least Firefox and Safari eval(s, {}) where s is a string as a direct eval call.
Good. Once Mike pointed out the issue, that's what we figured the answer was likely to be. We are happy with that answer.
Should it be the case that invoking unoverridden eval with 0 or 2 or more arguments is an EvalError, regardless of whether the call is direct or not?
What is the behavior of eval() and eval("alert('Hello, World!')", void 0) ?
Section 15.1.2.1 eval (x) specifies the behavior of the eval function "When the eval function is called with one argument x, the following steps are taken:" but section 15.1.2.1.1 specifies the behavior of the eval operator without mention to # of arguments
CallExpression that meets the following two conditions: 1. The Reference that is the result of evaluating the MemberExpression in the CallExpression has an environment record as its base value and its reference name is "eval". 2. The result of calling the abstract operation GetValue with that Reference as the argument is the standard built-in function defined in 15.1.2.1."
Sections 10.4.2 Entering eval code, and later the addenda both switch on the use of direct call but without any extra language about extra parameters. "15.1.2.1. Implementations are no longer permitted to restrict the use of eval in ways that are not a direct call. In addition, any invocation of eval that is not a direct call uses the global environment as its variable environment rather than the caller’s variable environment."
Since the direct call to eval distinction does not depend on the number of arguments, it seems that eval("alert('Hello, World!')", void 0) should resolve alert in the local environment and ignore the second and subsequent parameters. And that the behavior of (0, eval)("alert('Hello, World!')", void 0) is undefined because there is no else clause in section 15.1.2.1.