Multiple globals and direct/indirect eval
A few months back I noticed an interesting interaction between how direct eval is defined and multiple globals. What happens if, in one global, you call an eval from another global as if it were a direct eval? var indirect = otherGlobal.eval; eval = indirect; print(eval(this) === this); print(indirect(this) === this); Standards currently don't say what should happen here because it's multiple globals, so what should this do? IE9 and Opera print false both times for this. Firefox prints true, then false -- but only if the global and otherGlobal are from the same origin (so on pages with the same scheme/host/port, more or less). If they're from different origins (but have set document.domain to the same value) Firefox too prints false. Chrome and Safari throw an EvalError calling another window's eval (for both direct and indirect calls) without that window as |this| for the call. The Chrome/Safari behavior would resurrect the vestigial EvalError, so I don't think it makes sense. It also contradicts the specification of the steps in the definition of the eval function. Firefox's behavior is inconsistent and seems not amenable to host-agnostic specification as ECMA would require. Thus we are left with the IE9/Opera behavior, which seems sensible and natural to me: an eval function should always act in the context of the global from which it came. What needs to be done to standardize this behavior? And more generally, what needs to be done to begin standardizing multiple globals in ECMAScript, including issues like this one? Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Multiple globals and direct/indirect eval
Jeff, I think your real question reduces to this: //none strict mode code globalObj= function() {return this}(); print(otherGlobal.eval(this) === globalObj) //?? The two different calls and the indirect name in your example may make the question seen like it is about something else (direct/indirect eval). A more generally, do built-in functions capture their global environment at the time of their creation or do they they operate in the dynamic context of an ambient global environment. I hope it is the former. An example of the more general question would be: print((Object.getPrototypeOf(new otherGlobal.Array(0)) === Array.prototype) I believe the second example prints false for all browser implementations. Allen On Mar 3, 2011, at 2:39 PM, Jeff Walden wrote: A few months back I noticed an interesting interaction between how direct eval is defined and multiple globals. What happens if, in one global, you call an eval from another global as if it were a direct eval? var indirect = otherGlobal.eval; eval = indirect; print(eval(this) === this); print(indirect(this) === this); Standards currently don't say what should happen here because it's multiple globals, so what should this do? IE9 and Opera print false both times for this. Firefox prints true, then false -- but only if the global and otherGlobal are from the same origin (so on pages with the same scheme/host/port, more or less). If they're from different origins (but have set document.domain to the same value) Firefox too prints false. Chrome and Safari throw an EvalError calling another window's eval (for both direct and indirect calls) without that window as |this| for the call. The Chrome/Safari behavior would resurrect the vestigial EvalError, so I don't think it makes sense. It also contradicts the specification of the steps in the definition of the eval function. Firefox's behavior is inconsistent and seems not amenable to host-agnostic specification as ECMA would require. Thus we are left with the IE9/Opera behavior, which seems sensible and natural to me: an eval function should always act in the context of the global from which it came. What needs to be done to standardize this behavior? And more generally, what needs to be done to begin standardizing multiple globals in ECMAScript, including issues like this one? Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Harmony is a super-set of ES5 strict
On 02/25/11 13:26, Brendan Eich wrote: On Feb 25, 2011, at 1:12 PM, Boris Zbarsky wrote: On 2/25/11 4:08 PM, David Bruant wrote: I would tend to be more in favor of disallowing Harmony features in non-strict code (without explicit use strict directive) to avoid surprises (I'm nuancing below). I was under the impression that Harmony features would only be allowed for scripts that opt in to them (via the type or language of thescript tag or whatnot). Does that alleviate this concern? Yes, Harmony requires opt-in versioning, at least viascript type=application/ecmascript;version=6 (for example). An in-language use version 6 pragma has been discussed too, for fail-fast when code gets copied and pasted into the wrong container. However, some cats are (at least partly) out of the bag in Firefox: let, const, yield. Both let and yield require different opt-in already (type=application/javascript;version=1.7). Our let and const (especially) implementations are not Harmonious, and we still need to pin down precise semantics for Harmony, but they are close enough -- see Waldemar's post: http://www.mail-archive.com/es-discuss@mozilla.org/msg05017.html -- and generally used correctly (in future-proof ways) by their fans. We at Mozilla will bear the cost of shifting (mostly Firefox add-on) JS hackers over across any changes that do break let-, const-, and yield-using code. IOW, we renounce any potential de-facto standard in our let and const prototype implementations. We will break ourselves, and first, so that other implemntors don't have to reverse-engineer our prototypes (not that this is a credible problem: cross-browser JS code cannot use 'let' at all, and 'const' is not consistently implemented either). The function-in-block semantics in Firefox are un-Harmonious enough that we ban those in Firefox 4's strict mode implementation. Anyone writing cross-browser code will want to opt into Harmony, to shield downrev browsers from syntax errors. /be If we're saying that Harmony is strict-only, settable by a script tag, what will indirect eval and the Function constructor do if the evaluated code doesn't start with a use strict directive? Waldemar ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Multiple globals and direct/indirect eval
On 03/03/2011 04:41 PM, Allen Wirfs-Brock wrote: I think your real question reduces to this: //none strict mode code globalObj= function() {return this}(); print(otherGlobal.eval(this) === globalObj) //?? The two different calls and the indirect name in your example may make the question seen like it is about something else (direct/indirect eval). Not quite so. For the example I gave, yes -- but you could see the direct/indirect distinction by putting the code I provided inside a function (and a little more gussying to demonstrate behavior better): var global = this; function f() { var indirect = otherGlobal.eval; eval = indirect; print(eval(this) === this); print(eval(this) === global); print(eval(this) === otherGlobal); print(indirect(this) === this); print(indirect(this) === global); print(indirect(this) === otherGlobal); } new f(); IE9/Opera prints false/false/true and false/false/true. Chrome/Safari throws EvalError every time. Firefox prints true/false/false and false/false/true if otherGlobal is same-origin, false/false/true and false/false/true if otherGlobal is different-origin-but-same-document.domain. A more generally, do built-in functions capture their global environment at the time of their creation or do they they operate in the dynamic context of an ambient global environment. I hope it is the former. An example of the more general question would be: print((Object.getPrototypeOf(new otherGlobal.Array(0)) === Array.prototype) I believe the second example prints false for all browser implementations. This is an orthogonal issue, I believe, but I might as well respond since it's being discussed. There's a Firefox 4 bug that makes this not the case, ran out of time to fix it for release. It'll be fixed in 5.0, and I could imagine I might get a fix for it in a 4.0 point release, although with a fast release cycle that may not be necessary. If I recall correctly Nitro may be buggy this same way as well. I think Chrome/IE9/Opera did not demonstrate the bug in my testing. But in any case, printing false there is in my opinion the correct behavior. Jeff ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: LOG10E mystery constant
On 02/20/11 21:16, Mark S. Miller wrote: The specification of Math.LOG10E says: 15.8.1.5 LOG10E The Number value for the base-10 logarithm of e, the base of the natural logarithms; this value is approximately 0.4342944819032518. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. NOTE The value of Math.LOG10E is approximately the reciprocal of the value of Math.LN10. This is the only constant whose actual value differs across browsers: 0.43429448190325176 v8 version 2.3.9 [console: dumb] 0.4342944819032518 Chrome 11.0.672.2 dev 0.4342944819032518 Chrome 11.0.672.0 canary build 0.4342944819032518 FF 3.6.13 0.4342944819032518 FF 4.0b12pre 0.43429448190325176 Safari 5.0.1 (5533.17.8) 0.43429448190325176 WebKit nightly Safari 5.0.1 (5533.17.8, r78794) 0.4342944819032518 Opera 11.01 Build 1190 0.4342944819032518 IE 9.0.8080.16413CO Anyone know why? Which value is more correct? I don't really care about Math.LOG10E, but it's easier to write tests if only one value is actually correct. 0.4342944819032518 is correct. 0.43429448190325176 is wrong. The high-precision value of log10(e) is 0.4342944819032518276511289189166050822943970058036665661144... The closest IEEE double to this is 0.43429448190325181666793241674895398318767547607421875, which prints as 0.4342944819032518. 0.43429448190325176 evaluates to the different IEEE double 0.434294481903251761156781185491126962006092071533203125. On 02/20/11 21:26, John Cowan wrote: The two values are really the same value when represented as an IEEE double. The difference is in the printing routine, not the internal representation. Specifically, the ...2518 browsers are rounding, the ...25176 browsers are not. No, that's not what is happening here. Waldemar ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Harmony is a super-set of ES5 strict
On Mar 3, 2011, at 5:33 PM, Waldemar Horwat wrote: If we're saying that Harmony is strict-only, settable by a script tag, what will indirect eval and the Function constructor do if the evaluated code doesn't start with a use strict directive? Yeah, strict-only is probably not quite the right way to describe it. We discussed this a bit at the last face-to-face. Generally, Harmony still has to allow for the existence of non-Harmony code living and executing in the same heap. For example, a web page can contain script type=application/javascript.../script script type=application/javascript?version=HARMONY.../script and the bindings of both can see each other. If I remember right, the semantics we've talked about is that indirect eval defaults to ES5 non-strict. So the answer to your question is: the indirect-eval'ed code is non-strict. So I think it might be a little misleading to say Harmony is strict-only. It's a little more accurate to say that by default, Harmony code assumes the restrictions of ES5 strict mode and builds from there. However, it is possible to access and evaluate non-strict code via indirect eval, or -- in the browser setting, for example -- via access to code defined in non-Harmony. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Multiple globals and direct/indirect eval
On Mar 3, 2011, at 5:45 PM, Jeff Walden wrote: On 03/03/2011 04:41 PM, Allen Wirfs-Brock wrote: I think your real question reduces to this: //none strict mode code globalObj= function() {return this}(); print(otherGlobal.eval(this) === globalObj) //?? The two different calls and the indirect name in your example may make the question seen like it is about something else (direct/indirect eval). Not quite so. For the example I gave, yes -- but you could see the direct/indirect distinction by putting the code I provided inside a function (and a little more gussying to demonstrate behavior better): var global = this; function f() { var indirect = otherGlobal.eval; eval = indirect; print(eval(this) === this); print(eval(this) === global); print(eval(this) === otherGlobal); print(indirect(this) === this); print(indirect(this) === global); print(indirect(this) === otherGlobal); } new f(); I tried to simplify because the above depends upon too many possible points of variation including whether you correctly are/aren't treating the first three calls as direct evals. That decision, itself may be subject to the answer to the test I suggested. So it is probably best to resolve that one first. the following would also be interesting to test: new function f() { var indirectEval = eval; var indirectForeignEval = otherGlobal.eval; print(indirectEval === indirectForeignEval); //see if they are the same object print(indirectEval(this) === indirectForeignEval(this)); //do they evaluate to the same global object? eval=indirectForeign; print(eval(this)===this); } IE9/Opera prints false/false/true and false/false/true. Chrome/Safari throws EvalError every time. Firefox prints true/false/false and false/false/true if otherGlobal is same-origin, false/false/true and false/false/true if otherGlobal is different-origin-but-same-document.domain. A more generally, do built-in functions capture their global environment at the time of their creation or do they they operate in the dynamic context of an ambient global environment. I hope it is the former. An example of the more general question would be: print((Object.getPrototypeOf(new otherGlobal.Array(0)) === Array.prototype) I believe the second example prints false for all browser implementations. This is an orthogonal issue, I believe, but I might as well respond since it's being discussed. There's a Firefox 4 bug that makes this not the case, ran out of time to fix it for release. It'll be fixed in 5.0, and I could imagine I might get a fix for it in a 4.0 point release, although with a fast release cycle that may not be necessary. If I recall correctly Nitro may be buggy this same way as well. I think Chrome/IE9/Opera did not demonstrate the bug in my testing. But in any case, printing false there is in my opinion the correct behavior. I don't really agree that it is an orthogonal issue. The reason is because there are many places in the ES5 specification, including other built-in functions there the phrasing standard built-in function is used as well as the the phrase the global object. When extending that specification to an environment that includes multiple global object, these phrases should still be consistently applied. If one built-in function works as if it was lexically bound to a specific global object while another use the current ambient global environment (whatever that might mean) then the implementation would seem to be internal inconsistent. The specification of direct eval is one of the places that use this phrasing in the spec.. so it is quite relevant whether an implementations is internally consistent in this regard. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Harmony is a super-set of ES5 strict
On Mar 3, 2011, at 6:55 PM, David Herman wrote: So I think it might be a little misleading to say Harmony is strict-only. Who ever said that? :-P I've written that Harmony is based on ES5 strict. But even ES5 strict code can call non-strict code. Same goes for Harmony. It's a big shared-heap world out there... /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Harmony is a super-set of ES5 strict
So I think it might be a little misleading to say Harmony is strict-only. Who ever said that? :-P Yikes... not playing who-said-what. For whatever reason, Waldemar got the impression that someone said it, and I'm correcting the misconception, that's all. I've written that Harmony is based on ES5 strict. But even ES5 strict code can call non-strict code. Same goes for Harmony. It's a big shared-heap world out there... Right. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Multiple globals and direct/indirect eval
Hi Jeff, I agree that the spec should deal with multiple global objects. I'm aware of a few of the subtleties of multiple globals, but I wouldn't be surprised if there are more. Thanks for raising this one. I created a placeholder strawman last week, because I've been intending to get into this topic. I've given it some contents now, but there's more work to be done. Here's what I've got so far: http://wiki.ecmascript.org/doku.php?id=strawman:multiple_globals The Chrome/Safari behavior would resurrect the vestigial EvalError, so I don't think it makes sense. It also contradicts the specification of the steps in the definition of the eval function. I think I agree with this. Firefox's behavior is inconsistent and seems not amenable to host-agnostic specification as ECMA would require. I agree that we don't want things like the same-origin policy to show up in the ES spec. But I'm not sure I'm convinced there isn't a way to specify things loosely enough that the same-origin policy is consistent with whatever spec we end up with. I need to chew on that for a while, though. Thus we are left with the IE9/Opera behavior, which seems sensible and natural to me: an eval function should always act in the context of the global from which it came. Now this I think I don't agree with. The reason is that direct eval is really a static operator in ECMAScript, not an ordinary function call. It's more than a function call because, for example, it has access to the lexical environment. Now, it has this strange dynamic component where, if the value turns out dynamically *not* to be an evaluation function, then it degenerates into a function call. But this doesn't change the fact that direct eval is imbued with special static-operator powers not available to other function calls -- in particular, access to the lexical environment. At any rate, I can see two semantics that seem reasonable to me. First let me make up some terminology: an apparently direct eval is a call that's of the right form to be a direct eval, but whether it actually turns out to be a direct eval depends on the dynamic value of the callee. So the two alternatives: 1) an apparently direct eval is a direct eval if its callee is *any* evaluation function 2) an apparently direct eval is a direct eval *only* if its callee is the evaluation function of the same global context as the call site In either alternative, though, the global object of the eval'ed code is the same global object as the call site. At least for same-origin, semantics #1 agrees with what Firefox is doing. But either one makes sense to me. As for the same-origin stuff, I'm not yet sure what I think. I'll need to be schooled in the implications for the browser security model. What needs to be done to standardize this behavior? And more generally, what needs to be done to begin standardizing multiple globals in ECMAScript, including issues like this one? The above wiki page is a step in that direction, but there's more work to do. One thing that I think we have to do is nail down the notion of what callee values constitute an actual direct eval. It's not enough to say the eval function, which is as bogus a phrase as the global object. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss