On 17 Dec 2009, at 19:26, Drew Wilson wrote:

> That was my point earlier - for this to work, if you post getX and setX over 
> separately, they need to share a closure otherwise they don't work. 
> 
> Realistically, given Javascript's dynamic nature, you need to copy everything 
> reachable via the function's scope chain, and recursively copy everything 
> reachable via any reachable function's scope chain. In effect, copying a 
> function to worker context means bringing over the entire reachable heap. 
> Anything else you try to do is going to break in subtle ways when something 
> in the source context's scope chain isn't in the destination context's scope 
> chain.

Ah, there is my error. I thought closures were implemented by determining what 
the free variables of a function are, and then only keeping a reference to 
their value. For example:

(function() {
    var foo = 'banana';
    var bar = 'monkey';
    return function() {
        return [foo, eval('bar')];
    }
})()()

I thought it would return ['banana', undefined], but it returns ['banana', 
'monkey']. The whole context object is preserved, not just what is "relevant at 
first sight" (which is why Boris was talking about analysis complexity).

> I understand that we might like to treat code running in a worker as if it 
> were running in a same context as the parent page, so you could pass all the 
> same things to it that you could pass to any Javascript function, but the 
> situations are not identical - the only way something like this would be 
> feasible would be by adding limitations (i.e. not copying over the scope 
> chain of a function) that IMO fundamentally break Javascript semantics ; once 
> you do that, you might as well just use the existing string + eval() 
> mechanisms.

Yes, indeed, that would be confusing to explain what does and what doesn't 
work. I do suspect certain patterns will emerge to pass over functions and some 
self-defined context, but then there is no need to do this in VM code.

> 
> -atw

Thank you all for your effort to explain to me why this is not possible. I had 
a feeling that when people from Firefox/MIT, Google and Apple (certainly when I 
saw the subject of Oliver's thesis) were telling me it was impossible, that 
there was something I was missing. Now I know. Thank you for this mind-altering 
experience!

Then my only other request remains: could the summary of this discussion be 
placed in the FAQ, so others won't think you were short-sighted for not 
including it?

Greetings,

Jan Fabry


> 
> On Thu, Dec 17, 2009 at 2:06 AM, Oliver Hunt <oli...@apple.com> wrote:
> On Dec 17, 2009, at 10:03 PM, Boris Zbarsky wrote:
> 
> > On 12/17/09 12:48 AM, Boris Zbarsky wrote:
> >> It seems very difficult to me to come up with a "function cloning"
> >> solution that won't break in subtle ways when such functions are passed
> >> to it...
> >
> > I should clarify this.  It seems to me eminently possible to clone 
> > functions that only reference local (declared with var) variables and their 
> > arguments.  And maybe explicit |this| access; not sure.
> >
> > As soon as you're talking anything else, the situation gets very 
> > complicated, it seems to me.  That includes implicit property access on the 
> > global object.
> >
> > To make that clearer, consider these two functions, defined at global scope:
> >
> >  var x = 1;
> >  function f() {
> >    return x;
> >  }
> >  function g() {
> >    return Math;
> >  }
> >
> > If I understand your proposal correctly, passing f to a worker would pass 
> > across a function which always returns 1.  Passing g to a worker would do 
> > what?  Pass across a function that always returns the Math object from the 
> > web page scope?  If not, then how is Math different from x, exactly?  If 
> > yes, then why are we baking anything at all in at pass time?
> >
> > How is the f() example above affected if x is bound to an object, not to a 
> > number?
> 
> I think a more interesting case is the relatively common idiom of closures 
> for access protection, eg.
> 
> function MyObject() {
>    var x;
>    this.setX = function(_x) { x = _x };
>    this.getX = function() { return x }
> }
> 
> What should worker.postMessage(new MyObject) do if we were to try and 
> serialise the functions? obviously you don't want them each to have 
> (effectively) separate closures, and you can't just substitute their 
> containing scope with the global object.
> 
> > -Boris
> 
> 
> --Oliver
> 
> 

Reply via email to