Closed Bug 600677 Opened 15 years ago Closed 14 years ago

Object.freeze(proxy) does not call the proxy handler's fix() trap

Categories

(Core :: JavaScript Engine, defect, P2)

x86
macOS
defect

Tracking

()

RESOLVED WONTFIX
Tracking Status
blocking2.0 --- -
status2.0 --- wanted

People

(Reporter: tomvc.be, Unassigned)

References

Details

(Whiteboard: [fixed in tracemonkey][need better unit tests][Doc: when this lands, the fix trap will be called unlike previous versions])

Attachments

(1 file, 2 obsolete files)

Calling any of Object.preventExtensions, Object.seal or Object.freeze on a trapping harmony:proxy does not call the handler's fix() trap. Instead, the handler's getOwnPropertyNames() trap is invoked, and for each returned property name, a getOwnPropertyDescriptor(name) trap is invoked. It appears as if the proxy implementation is trying to shortcut the fix() trap and trying to reconstruct a property descriptor map of the object directly. Testcase: var p = Proxy.create({ fix: function() { return {foo:2}; } }); Object.preventExtensions(p); => TypeError: getOwnPropertyNames is not a function
Priority: -- → P2
waldo, you guys didn't wire up the proxy's fix infrastructure to the new object op
(suggesting waldo for this but I can take back after compartments landed if you are overloaded) proxy_DeleteProperty, NULL, /* enumerate */ NULL, /* typeof */ proxy_TraceObject, NULL, /* fix */ NULL, /* thisObject */ proxy_Finalize, /* clear */ }
Assignee: general → jwalden+bmo
blocking2.0: --- → ?
blocking2.0: ? → betaN+
blocking2.0: betaN+ → -
status2.0: --- → wanted
Is the test case valid? {foo:2} doesn't look like a valid propertyDescriptor map. Shouldn't we rather test with {foo: {value:2}}? The bug is still occuring in FF4b11. Tom's description sounds familiar. It sounds like the called method is the one defined in handlerMaker (http://wiki.ecmascript.org/doku.php?id=harmony:proxies#examplea_no-op_forwarding_proxy): fix:function() { if (Object.isFrozen(obj)) { return Object.getOwnPropertyNames(obj).map(function(name) { return Object.getOwnPropertyDescriptor(obj, name); }); } // As long as obj is not frozen, the proxy won't allow itself to be fixed return undefined; // will cause a TypeError to be thrown }
This is a really trivial fix. Can we try to get a patch for this?
Want this in the release branching next week... /be
Assignee: jwalden+bmo → gal
Attached patch Add fix hook to proxies. (obsolete) — Splinter Review
This passes the modified test from comment 3. Dunno if I'm getting the resolved props right, though.
Attachment #526507 - Flags: review?(gal)
Comment on attachment 526507 [details] [diff] [review] Add fix hook to proxies. You want JSITER_OWNLY and JSITER_HIDDEN, since we want non-enumerable properties as well.
Attachment #526507 - Flags: review?(gal) → review+
Attached patch Add fix hook to proxies. (obsolete) — Splinter Review
Attachment #526507 - Attachment is obsolete: true
Assignee: gal → josh
Rebased.
Attachment #526511 - Attachment is obsolete: true
Keywords: checkin-needed
Whiteboard: [push to tracemonkey]
Status: NEW → ASSIGNED
Keywords: checkin-needed
Whiteboard: [push to tracemonkey] → [fixed in tracemonkey]
Most of the tests related to fixing proxies on <http://hg.ecmascript.org/tests/harmony/> now pass, except for one, which has to do with recursive fixing: var proxy = Proxy.create({ fix: function() { Object.preventExtensions(proxy); // triggers 'fix()' recursively return {}; } }); Object.preventExtensions(proxy); // triggers 'fix' Result: InternalError: too much recursion Expected: a TypeError We reached consensus on this behavior in a TC39 meeting last year. Admittedly, it's well hidden on the semantics page: <http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics> "Note: recursive fixing should be disallowed. If fix() is called on a proxy handler while the same proxy is already being fixed (an earlier call to fix() is already on the stack), a TypeError should be thrown. "
Tom, thanks for checking that. Could you file a new bug and CC me, please?
Comment on attachment 526530 [details] [diff] [review] Add fix hook to proxies. Please carry along r+. Thanks, /be
Attachment #526530 - Flags: review+
Depends on: 652803
The current patch doesn't seem to fix the issue for function proxies: Testcase: var handler = { get: function(rcvr, name) { if (name === 'isTrapping') return true; }, fix: function() { return { isTrapping: { value: false } }; } }; var p = Proxy.createFunction(handler, function(){}, function(){}); assert(p.isTrapping); Object.preventExtensions(p); assert(! p.isTrapping); The call to preventExtensions still fails. It works fine for object proxies though (replace Proxy.createFunction by Proxy.create)
Boo. Looks like I forgot to change >1146 NULL, /* fix */ in FunctionProxyClass. Could someone whip that up?
Blocks: 655112
Status: ASSIGNED → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
I'd like to reopen, because the test case is not entirely relevant (In reply to comment #17) > http://hg.mozilla.org/mozilla-central/rev/6947160cc064 ----- > var p = Proxy.create({ fix: function() { return {foo: {value: 2} }; } }); > Object.preventExtensions(p); > reportCompare(p.foo, 2, "property exists"); > p.foo = 3; > reportCompare(p.foo, 2, "proxy is frozen"); p.foo === 2 the second time not because the proxy is frozen (it's actually not /frozen/, but extension is prevented), but rather because foo is non-writable (implicit in the returned property descriptor). I think the first test case should stop before "p.foo = 3" and that another test case should test that p is non extensible (a call to Object.isExtensible should be enough).
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Whiteboard: [fixed in tracemonkey] → [fixed in tracemonkey][need better unit tests]
Go ahead :) I am always for test cases. I think you should also do something like p.newProperty = 'bla'; assertEq('newProperty' in p, false);
Keywords: dev-doc-needed
Whiteboard: [fixed in tracemonkey][need better unit tests] → [fixed in tracemonkey][need better unit tests][Doc: when this lands, the fix trap will be called unlike previous versions]
No longer blocks: harmony:proxy
Assignee: josh → evilpies
Flags: in-testsuite-
Assignee: evilpies → general
(In reply to Josh Matthews [:jdm] from comment #16) > Boo. Looks like I forgot to change > > >1146 NULL, /* fix */ > > in FunctionProxyClass. Could someone whip that up? This still hasen't been fixed, and the tests are incomplete, please somebody with Proxies fix that.
I think a better use of everyone's time would be to work on direct proxies (bug 703537) which solves design issues of current proxies.
Yeah, I think direct proxies are the way, the truth, and the life here.
Status: REOPENED → RESOLVED
Closed: 15 years ago14 years ago
Keywords: dev-doc-needed
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: