Harmony helpwanted: Proxy, Map discrepancy between V8 and SpiderMonkey

# Alex Vincent (13 years ago)

everyone. I've been tinkering around with Harmony's Proxy and WeakMap implementations, and I've run into a problem. A Jasmine test which works fine in Mozilla Firefox Aurora builds throws an exception in Google Chrome Dev builds, with the experimental JavaScript features enabled.

I really need some help in identifying whether the bug is in Aurora, Chrome, or in my own code. I wrote all of the JavaScript code in the project, and to my knowledge none of it is browser- or engine-specific; it should all conform to Harmony and ECMAScript standards unless I have a bug in my code.

The concept I'm working on is using Proxy to create prototype objects for constructor functions, and using a membrane like Tom van Cutsem's to isolate private properties from public ones.

Steps to reproduce are below. I have partially reduced my testcase so that other parts of my project are not run as part of the test, and no Makefile or other scripting commands are necessary.

Terminal commands: hg clone --branch ProxyConstructorTest code.google.com/p/dimensionalmap test-proto-membrane cd test-proto-membrane/ hg update --rev 5992f4c09a38

Open V8-SpiderMonkey-test.html in Mozilla Firefox Aurora and in Google Chrome Dev 19.

In FF Aurora, all tests pass. In GC Dev: TypeError: Object.getOwnPropertyDescriptor called on non-object at Function.getOwnPropertyDescriptor (native) at Object.getDesiredPropertyOwner (file:///home/ajvincent/repositories/test-proto-membrane/ProtoMembrane/Membrane.js:59:34) at Object.foo (file:///home/ajvincent/repositories/test-proto-membrane/ProtoMembrane/Membrane.js:82:31) at [object Object].<anonymous> (file:///home/ajvincent/repositories/test-proto-membrane/spec/ProtoMembrane.js:94:21)

The function executing is in ProtoMembrane/Membrane.js:

getDesiredPropertyOwner: function(originalThis, name) { var _thisObj = this.getPrivate(originalThis); if (_thisObj == originalThis) { while (_thisObj && !Object.getOwnPropertyDescriptor(Object.getPrototypeOf(_thisObj), name)) { _thisObj = Object.getPrototypeOf(_thisObj); } } return _thisObj; },

In Aurora, _thisObj != originalThis, so it just moves on. In GC Dev, _thisObj == originalThis, and on the second iteration of the while loop, Object.getPrototypeOf(_thisObj) is null. Object.getOwnPropertyDescriptor(null, "foo"); throws the TypeError.

# Brandon Benvie (13 years ago)

I think this may be related a bug I was seeing where the internal Object.getOwnPropertyNames function was the source of the error, claiming it had returned duplicate properties. It was for something like createFunction(name, onConstruct, onCall) that would make composite functions. I think it had something to do with the fact that I was trying to maintain a unified public object identity so I was usding a kind of double proxy. It seemed like there was a bug internal with the implementation but I couldn't pin down exactly what it was. Just that it was specifically related to proxies and foolishing with constructor/prototype identity.

The code for it is here: Benvie/meta-objects/blob/master/lib/FunctionBuilder.js

You can see at the bottom where I'm specifically filtering the provided results out in gOPN. I'm using a modified Direct Proxy shim but I believe I was able to rule out anything external and that the bug was internal.

# Andreas Rossberg (13 years ago)

On 20 March 2012 08:18, Alex Vincent <ajvincent at gmail.com> wrote:

Hi, everyone. I've been tinkering around with Harmony's Proxy and WeakMap implementations, and I've run into a problem. A Jasmine test which works fine in Mozilla Firefox Aurora builds throws an exception in Google Chrome Dev builds, with the experimental JavaScript features enabled.

I really need some help in identifying whether the bug is in Aurora, Chrome, or in my own code. I wrote all of the JavaScript code in the project, and to my knowledge none of it is browser- or engine-specific; it should all conform to Harmony and ECMAScript standards unless I have a bug in my code.

Proxies are rather new, so it might very well be a bug in V8. There might also be minor implementation differences between the two systems, since the proxy spec wasn't entirely complete yet and has changed in some details, even before the advent of direct proxies.

I would need a small enough test case to verify that. Is there a chance that you can narrow down the exact point where the behaviours of Firefox and Chrome start to differ unexpectedly? For example, with some printf debugging?

# Alex Vincent (13 years ago)

www.alexvincent.us/temp/ProxyCtor/V8-SpiderMonkey-test.html

I reduced the testcase quite severely. It's a combination between Proxy and WeakMap. I store the proxy as a key for the WeakMap, and then expect to get back that proxy through Object.getPrototypeOf.

# Andreas Rossberg (13 years ago)

On 21 March 2012 21:00, Alex Vincent <ajvincent at gmail.com> wrote:

www.alexvincent.us/temp/ProxyCtor/V8-SpiderMonkey-test.html

I reduced the testcase quite severely. It's a combination between Proxy and WeakMap. I store the proxy as a key for the WeakMap, and then expect to get back that proxy through Object.getPrototypeOf.

Thanks, that helped. I reduced it further and made it into a V8 bug, see:

code.google.com/p/v8/issues/detail?id=2021

In particular, it has nothing to do with weak maps, only with setting a function.prototype property to a proxy. A fix is on the way ( codereview.chromium.org/9837008). In the meantime, as a workaround you could create your object with Object.create instead of using a constructor function.

Sorry for the inconvenience!