Closed
Bug 753402
Opened 14 years ago
Closed 11 years ago
Harmony proxies: Weird behaviour on objects when Object.prototype.__proto__ is a proxy.
Categories
(Core :: JavaScript Engine, defect)
Tracking
()
RESOLVED
FIXED
People
(Reporter: djvj, Unassigned)
References
Details
(Whiteboard: [js:p3])
Noticed this behaviour when debugging a ASSERT in Ion. Here's the test code:
CODE:
-----
var counter = 0;
var p = Proxy.create({
has : function(id) {
print("HAS: counter=" + counter + " id=" + id);
++counter;
if (counter == (12)) {
print("HAS: here");
obj.__proto__ = null;
print("HAS: here2");
return true;
}
},
get : function(id) {
print("HAS: counter=" + counter + " id=" + id);
if (id == 'xyz')
return 10;
}
});
obj = { xyz: 1};
for (var i = 0; i != 100; ++i) {
print("before obj.xyz (i=" + i + ")");
var s = obj.xyz;
print("after obj.xyz (i=" + i + ")");
if (i == 10) {
print("HERE1");
delete obj.xyz;
Object.prototype.__proto__ = p;
}
}
-----
OUTPUT:
-----
after obj.xyz (i=0)
before obj.xyz (i=1)
after obj.xyz (i=1)
before obj.xyz (i=2)
after obj.xyz (i=2)
before obj.xyz (i=3)
after obj.xyz (i=3)
before obj.xyz (i=4)
after obj.xyz (i=4)
before obj.xyz (i=5)
after obj.xyz (i=5)
before obj.xyz (i=6)
after obj.xyz (i=6)
before obj.xyz (i=7)
after obj.xyz (i=7)
before obj.xyz (i=8)
after obj.xyz (i=8)
before obj.xyz (i=9)
after obj.xyz (i=9)
before obj.xyz (i=10)
after obj.xyz (i=10)
HERE1
before obj.xyz (i=11)
HAS: counter=0 id=xyz
after obj.xyz (i=11)
before obj.xyz (i=12)
HAS: counter=1 id=xyz
after obj.xyz (i=12)
before obj.xyz (i=13)
HAS: counter=2 id=xyz
after obj.xyz (i=13)
before obj.xyz (i=14)
HAS: counter=3 id=xyz
after obj.xyz (i=14)
before obj.xyz (i=15)
HAS: counter=4 id=xyz
after obj.xyz (i=15)
before obj.xyz (i=16)
HAS: counter=5 id=xyz
after obj.xyz (i=16)
before obj.xyz (i=17)
HAS: counter=6 id=xyz
after obj.xyz (i=17)
before obj.xyz (i=18)
HAS: counter=7 id=xyz
after obj.xyz (i=18)
before obj.xyz (i=19)
HAS: counter=8 id=xyz
HAS: counter=9 id=xyz
after obj.xyz (i=19)
before obj.xyz (i=20)
HAS: counter=10 id=xyz
HAS: counter=11 id=xyz
HAS: here
HAS: here2
:/tmp/test.js:14: TypeError: can't convert id to primitive type
-----
There are a couple of issues here. One, note that after Object.prototype.__proto__ is changed to point to proxy p, the 'has' function on the handler is invoked. This seems out of sync with the Harmony spec.
Secondly, note that 'has' is invoked twice on iteration i=19 and i=20 of the loop. I think this may potentially be a jaeger-compile trigger that's causing that behaviour.
Comment 1•14 years ago
|
||
A short test for the first "has" bug:
var p = Proxy.create({
has: function (id) { throw "FAIL"; },
get: function (id) { return 10; }
});
var obj = Object.create(p);
assertEq(obj.x, 10);
In mozilla-central tip, 'obj.x' triggers a call to the 'has' trap, with this stack:
js::Proxy::has
proxy_LookupGeneric
JSObject::lookupGeneric
LookupPropertyWithFlagsInline
js_GetPropertyHelperInline
js::GetPropertyHelper
js::GetPropertyOperation
Direct proxies will not fix this.
Comment 2•14 years ago
|
||
And here is a short test for the second bug:
// |jit-test| mjitalways
var c = 0;
var p = Proxy.create({has: function (id) { c++; }});
var obj = Object.create(p);
for (var i = 0; i < 4; ++i)
obj.xyz;
assertEq(c, 4);
This fails due to some code under GetPropMaybeCached in methodjit/PolyIC.cpp. Toward the bottom of that function there's this:
if (!monitor.recompiled() && pic->shouldUpdate(f.cx)) {
GetPropCompiler cc(f, script, obj, *pic, name, stub);
if (!cc.update())
THROW();
}
Value v;
if (cached) {
if (!GetPropertyOperation(f.cx, f.pc(), f.regs.sp[-1], &v))
THROW();
} else {
if (!obj->getProperty(f.cx, name, &v))
THROW();
}
The hit trap can be called twice: once from cc.update(), which does a lookup; and then again from obj->getProperty().
I suspect cc.update() should be changed to avoid firing proxy traps, but I can't take this bug.
Updated•14 years ago
|
Whiteboard: [js:p3]
| Assignee | ||
Updated•12 years ago
|
Assignee: general → nobody
Updated•11 years ago
|
Status: NEW → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
You need to log in
before you can comment on or make changes to this bug.
Description
•