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