Here is another way to think about it.

The built-in function object that is the initial value of the global  "eval"  
(defined in 15.1.2.1) is a non-strict function. Hence anything it does defaults 
to "non-strict" and it uses the global environment as the VariableEnvironment 
for the code it evaluates.  However, if the argument code contains an use 
strict directive, then it uses a new child environment of the global 
environment as the VariableEnvironment.   This is all specific defined behavior 
of the built-in eval function object and is completely independent of who calls 
the function or how the caller accessed the function.

An "indirect eval" is any invocation of the above function.

A "direct eval" is essentially a special syntactic from in the ES5 language 
with its own specific semantics. Some people have talked about it as the "eval" 
operator.  A direct eval does not call the built-in eval function object.  
Instead, it has its own slightly different semantics that can be directly 
implemented at the call site.  These semantics include access to the 
immediately surrounding LexicalEnvironment and the propagation of strictness 
into the eval code.

Allen


On Feb 18, 2011, at 4:52 AM, Dmitry A. Soshnikov wrote:

> Have no idea what with mail sever again, there is no this message there 
> (links in message?). The original question is below:
> 
> On 18.02.2011 11:51, Dmitry A. Soshnikov wrote:
>> 
>> Hello,
>> 
>> As is known, indirect `eval` evaluates in the global context (this note is 
>> not for the TC-39 group of course, but for all other who read this list). 
>> But what is the big rationale of that indirect eval is allowed to create a 
>> global binding even _regardless_ the fact that the global code is _strict_?
>> 
>> I.e.:
>> 
>> "use strict";
>> 
>> eval("var x = 10;"); // direct
>> this.eval("var y = 20;"); // indirect
>> 
>> console.log(typeof x, typeof y); // "undefined", "number"
>> 
>> The only _practical_ rationale of the indirect `eval` regarding the strict 
>> mode is that via its call it's possible to get the global object via `this` 
>> value from any place (since just returning `this` won't work as it's set to 
>> `undefined` in a simple function call):
>> 
>> var global = (function () { return this; })(); // ES3, non-strict ES5 way
>> 
>> var global = ("indirect", eval)("this"); // strict ES5
>> 
>> Which else practical/theoretical/academical rationales of the indirect eval 
>> are? And what again the rationale that it's allowed to create the global 
>> binding (i.e. not in the "sandbox" environment, but reusing 
>> `VariableEnvironment` of the "caller" -- not a direct caller though, but the 
>> adjusted -- the global scope)? Could you clarify this, I want to give a more 
>> concrete explanations for my readers. 
>> 
>> P.S.:
>> 
>> Just recently Allen brought a good addition (well, a reminder even better to 
>> say, since I also wanted to add it ;) to mention this subtle case with 
>> indirect eval and it's ability to affect the global environment regardless 
>> the strict mode: 
>> http://dmitrysoshnikov.com/ecmascript/es5-chapter-2-strict-mode/#comment-5831
>> 
>> It's without doubts a very needed addition and as is said -- a subtle case, 
>> but still -- what are the exact rationales for that? I mentioned this case 
>> in Allen's blog before, and though that this is a bug of the spec -- 
>> http://www.wirfs-brock.com/allen/posts/39#comment-46
>> 
>> Allen answered that this is related with complexity of implementation, here:
>> 
>> "An indirect eval called from strict code is strict only if the eval code 
>> explicit contains an “use strict;” directive. It does not “inherit” the 
>> strictness of its caller.
>> Every call is potentially an indirect eval call. If the strictness of 
>> indirect evals depended upon the strictness of the caller then we would have 
>> to pass the strictness of the caller through every call. That would require 
>> either an extra implicit parameter on every call or the ability to a callee 
>> to examine the call stack to to determine the strictness of its caller. We 
>> don’t want to force this on implementations."
>> 
>> The basic idea is seems clear -- we need to pass a flag that the code of an 
>> inner function (from which indirect `eval` was called) is strict, but if the 
>> _global_ code is strict -- and indirect `eval` always evaluates in the 
>> global context, and moreover, if the global code is strict that means _any_ 
>> inner function (except those which are created via `Function` constructor 
>> and have no own strictness) is automatically also strict:
>> 
>> "use strict";
>> 
>> (function foo() {
>>   // this code is also strict
>>   ("indirect", eval)("var x = 10;");
>> })();
>> 
>> console.log(x); // 10
>> 
>> is it also required to pass special flags to handle this case?
>> 
>> Thanks,
>> Dmitry.
> 
> _______________________________________________
> es-discuss mailing list
> [email protected]
> https://mail.mozilla.org/listinfo/es-discuss

_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to