Re: Multiple globals and direct/indirect eval

2011-03-04 Thread David Bruant
[Adding WhatWG and public-script-coord (WebIDL) to the discussion.
Discussion is ongoing :
- Start of thread :
https://mail.mozilla.org/pipermail/es-discuss/2011-March/012915.html
- Strawman by Dave Herman:
http://wiki.ecmascript.org/doku.php?id=strawman:multiple_globals )]

---
Hi,

I am wondering if ECMAScript is the right place to standardize this.
Web browsers face multiple global object via a mecanism which isn't
under the ECMAScript scope (namely HTMLIFrameElements
(http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#htmliframeelement)
which aren't even DOM but HTMLDOM-specific).
Other ECMAScript implementations could face the issue of having several
globals but with other non-HTMLDOM use cases. For that reason, I think
it'd be dangerous for ECMAScript to standardize anything on the topic.

To answer Jeff Walden's final questions, in my opinion, WebIDL would be
a way better place to standardize this. ECMAScript could at most provide
guidelines for ECMAScript implementors who would have to face this issue
(gathering feedback and experience from implementations).

Cheers,
David



Le 03/03/2011 23:39, Jeff Walden a écrit :
 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: [whatwg] Multiple globals and direct/indirect eval

2011-03-04 Thread Allen Wirfs-Brock

On Mar 4, 2011, at 8:39 AM, Mark S. Miller wrote:

 I certainly agree that there needs to be a better interface boundary
 between w3c/whatwg specs and ECMA specs. Too many issues -- like the
 semantics of multiple globals -- fall in the gaps between the two
 organizations. The WebIDL's JS binding and public-script-coord are good
 places to work out these boundary issues. WebIDL, WebIDL's JS binding, and
 ES-next should co-evolve so that the rest of the w3c/whatwg specs ideally
 interface to JS only through WebIDL, and WebIDL's JS binding ideally depend=
 s
 only on standard elements of ES-next. Of course, there will always be a nee=
 d
 to accommodate some special cases that can't be specified that way, like th=
 e
 semantics of cross-origin heap sharing.
 
 My main regret in saying this is that WebIDL, having evolved from Corba IDL=
 ,
 is notationally almost pessimal for encouraging good JS interface design. W=
 e
 have all been suffering the consequences of that. I fear that WebIDL, and
 its entrenched place within the w3c/whatwg API design process, dooms us to =
 a
 continual flood of browser APIs hostile to JS programmers.

I also agree that there are issues here that need a common resolution.  
However, it is less clear to me that that WebIDL is the best (or only) place it 
needs to be addressed.  WebIDL defines how abstract interface definitions map 
to the  concrete features of various languages.  However, there are places in 
web specifications where specific semantic actions (not interfaces) must be 
described in a manner that that transcend all languages.  These are  not 
language binding issues, but rather concerns that relate to the semantics 
that must be commonly support by any language that executes in the web 
application environment. 

Essentially, there is a language independent web apps scripting environment.  
More concretely, you might think of this as the common shared browser heap.  
This environment should be specified in or as one of the core browser/web app 
specifications.  If that is done, then language bindings can be specified the 
context of that specification. Some of characteristics of this scripting 
environment may include things like:

Web app objects encapsulate state that may include reference to other objects.
The state of  objects can be manipulated/access via put/get/call operations to  
their methods and attributes.
There are multiple independent heaps.
Heaps have well defined lifetimes.
Each object exists within a specific heap and has unique identity with respect 
to its heap.
Objects within a common heap may directly reference and interact with each 
other, constrained only by their specific language semantics.
References between objects in different heaps must be intermediated via a 
mechanism with a specified semantics.
Multiple Script global objects may exist in a single heap.
etc.

The specification of this environment should sufficiently complete that all 
language independent scripting characteristics of the browser (for example 
cross-origin policies) to be specified strictly in terms of that specification 
and without references to any specific language binding.

Done well, this would give us a much cleaner separation between the web app 
platform and specific scripting language.  At that point, some of the issues of 
current concern then really do become language binding issues.  For example, 
how does  the concept of multiple Script global objects map onto the 
ECMAScript language.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Multiple globals and direct/indirect eval

2011-03-04 Thread Allen Wirfs-Brock

On Mar 3, 2011, at 9:22 PM, David Herman wrote:

 
 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.

Dave, I completely agree with this intent.  direct eval was intended to 
perform as if it was an operator and hence has fixed call site specific 
semantics.  We may quibble about the details of the specification regarding how 
we identify such direct evals but I don't think there is any question about how 
a direct eval is supposed to behave once you are sure it is a direct eval.   If 
we think a call site is a direct eval but in fact it would access a foreign 
global object then it must have been misidentified as a direct eval as such 
access is not part of the intended direct eval behavior. 


 
 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.

there is a third alternative:  there is a single unique eval function object 
value taht is the initial value of the global eval binding in all global 
contexts.

A directly related questions is what do we expect for eval ===otherGlobal.eval  
assuming that the initial value of the global eval binding has not been changed 
in either context.
Assuming that a script has executed:
   const originalEval = eval;

then consider  the code:
   eval = otherGlobal.eval;
   if (eval !== originalEval) eval();

Based upon original ES5 intent, the eval clause in the then clause should never 
be treated as a direct eval as it is clearly observable that eval has been 
tampered with.  To me, this would preclude alternative 1 (assuming different 
eval functions are not ===) but it would allow for alternative 2 or my 
alternative 3.

It's when we look at the indirect eval case that other issues arise. A 
evaluation function when called (not a direct eval) has access to some global 
environment.  Is it the global environment that the eval function originated 
from or is it the ambient global environment of the caller?  Either is 
plausible.  However, the global of origin option would preclude by alternative 
3 above (single shared eval function) as it suggests that it would be possible 
for values that compare === to have observably different behavior when invoked. 
Not something we want.  This seems to reduce us to two overall alternatives:
1) each global context has a === unique evaluation function that captures that 
global context and which is used as the global context when the function is 
invoke.
2) there is a single === unique evaluation function that is shared by all 
global contexts.  When the function is called it uses the ambient global 
context of its caller.

The main problem with alternative 2 is that I don't believe that current 
browsers generally conform to the === requirement.  Other interesting behavior 
to compare among browsers is:
var a= new otherGobal.Array;
var b= otherGobal.eval(new Array);
print(Object.getPrototypeOf([ ])===Object.getPrototypeOf(a));
print(Object.getPrototypeOf(a)===Object.getPrototypeOf(b));

I believe we will see that currently browser generally answer false to the 
first test and that results of the second test may vary.  If built-ins 
generally behave as if they have captured their origin global environment, then 
it would seem consistent that the eval function should behave in the same 
consistent manner.

These all leads me to conclude that the likely resolution is:
1) each global context has a === unique evaluation function that captures that 
global context and which is used as the global context when the function is 
called (not a direct eval).




 
 As for the same-origin stuff, I'm not yet 

Multiple globals and direct/indirect eval

2011-03-03 Thread Jeff Walden

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

2011-03-03 Thread Allen Wirfs-Brock
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: Multiple globals and direct/indirect eval

2011-03-03 Thread Jeff Walden

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: Multiple globals and direct/indirect eval

2011-03-03 Thread Allen Wirfs-Brock

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: Multiple globals and direct/indirect eval

2011-03-03 Thread David Herman
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