On 5 October 2011 21:00, Andreas Rossberg <rossb...@google.com> wrote:
> On 5 October 2011 18:57, Andreas Rossberg <rossb...@google.com> wrote:
>> FIXING PROXIES
>>
>> A particularly worrisome side effect is fixing a proxy. The proxy
>> semantics contains a lot of places saying "If O is a trapping proxy,
>> do steps I-J." However, there generally is no guarantee that O remains
>> a trapping proxy through all of I-J!
>>
>> Again, an example:
>>
>> ----------------
>> var handler = {
>>  get set() { Object.freeze(p); return undefined },
>>  fix: function() { return {} }
>> }
>> var p = Proxy.create(handler)
>> p.x
>> ----------------
>>
>> Firefox 7: TypeError on line 1: getPropertyDescriptor is not a function
>> V8: TypeError: Object #<Object> has no method 'getPropertyDescriptor'
>
> Whoops, sorry, I just saw that I screwed up that example. That
> behaviour is perfectly fine, of course. Don't have my notes here, I'll
> deliver the proper example tomorrow.

Here we go (the last line should have been an assignment):

----------------
var handler = {
  get set() { Object.freeze(p); return undefined },
  fix: function() { return {} }
}
var p = Proxy.create(handler)
p.x = 4
----------------

Firefox 7: TypeError on line 1: proxy was fixed while executing the handler
V8: TypeError: Object #<Object> has no method 'getOwnPropertyDescriptor'

So Firefox rejects this (consistently with its treatment of other
methods), while V8 tries to go on with the DefaultPut, using the traps
from the handler that it still happens to have around. This is not
quite what the rules of DefaultPut imply, but what the (inconsistent)
note says.

A related nit: even for freeze and friends, the restriction on
recursive fix is NOT enough as currently stated in the proxy
semantics. Consider:

------------------
var handler = {
  get fix() { Object.seal(p); return {} }
}
var p = Proxy.create(handler)
Object.freeze(p)
------------------

Strictly speaking, there actually is no recursive execution of fix()
-- the recursion occurs a few steps earlies, when we try to _get_ the
fix function. Firefox rejects this nevertheless:

TypeError on line 2: proxy was fixed while executing the handler

V8 bails out with a stack overflow:

RangeError: Maximum call stack size exceeded

While this might merely be a nit, it shows that it is _not_ generally
enough to only prevent fixing while _executing_ traps. To be
conservative, it seems like we perhaps have to disallow any reentrant
use of freeze/seal/prevenExt at any point in _any_ internal method of
the same object. But how spec that?

/Andreas
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to