Bug 683361 - Fix part 6: add and call Proxy::objectClassIs (r=waldo)
authorLuke Wagner <luke@mozilla.com>
Wed, 28 Sep 2011 08:48:16 -0700
changeset 77772 b626aecfddf79d6d3333b19f625f3d6514d5b602
parent 77771 638433a972a31d82060b30cb45db3a3e69f11fae
child 77773 f3022823eb876895edb22eb8aaca29fa3787ad42
push id21239
push usermwu@mozilla.com
push dateThu, 29 Sep 2011 08:20:44 +0000
treeherdermozilla-central@e7854b4d29ba [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs683361
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 683361 - Fix part 6: add and call Proxy::objectClassIs (r=waldo)
js/src/jit-test/tests/basic/testCrossCompartmentTransparency2.js
js/src/jsobjinlines.h
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jswrapper.cpp
js/src/jswrapper.h
--- a/js/src/jit-test/tests/basic/testCrossCompartmentTransparency2.js
+++ b/js/src/jit-test/tests/basic/testCrossCompartmentTransparency2.js
@@ -8,8 +8,18 @@ var number = g.eval("new Number(42)");
 var bool = g.eval("new Boolean(false)");
 var string = g.eval("new String('ponies')");
 assertEq(JSON.stringify({n:number, b:bool, s:string}), "{\"n\":42,\"b\":false,\"s\":\"ponies\"}");
 assertEq(JSON.stringify({arr:array}), "{\"arr\":[1,2,3]}");
 assertEq(JSON.stringify({2:'ponies', unicorns:'not real'}, array), "{\"2\":\"ponies\"}");
 assertEq(JSON.stringify({42:true, ponies:true, unicorns:'sad'}, [number, string]), "{\"42\":true,\"ponies\":true}");
 assertEq(JSON.stringify({a:true,b:false}, undefined, number), "{\n          \"a\": true,\n          \"b\": false\n}");
 assertEq(JSON.stringify({a:true,b:false}, undefined, string), "{\nponies\"a\": true,\nponies\"b\": false\n}");
+
+var o = Proxy.create({getPropertyDescriptor:function(name) {}}, Object.prototype);
+var threw = false;
+try {
+    print([].concat(o).toString());
+} catch(e) {
+    assertEq(e instanceof TypeError, true);
+    threw = true;
+}
+assertEq(threw, true);
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -1748,17 +1748,17 @@ BoxedPrimitiveMethodGuard(JSContext *cx,
     *v = Behavior::extract(thisv.toObject().getPrimitiveThis());
     return true;
 }
 
 inline bool
 ObjectClassIs(JSObject &obj, ESClassValue classValue, JSContext *cx)
 {
     if (JS_UNLIKELY(obj.isProxy()))
-        return obj.getProxyHandler()->classPropertyIs(cx, &obj, classValue);
+        return Proxy::objectClassIs(&obj, classValue, cx);
 
     switch (classValue) {
       case ESClass_Array: return obj.isArray();
       case ESClass_Number: return obj.isNumber();
       case ESClass_String: return obj.isString();
       case ESClass_Boolean: return obj.isBoolean();
     }
     JS_NOT_REACHED("bad classValue");
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -309,17 +309,17 @@ ProxyHandler::hasInstance(JSContext *cx,
 JSType
 ProxyHandler::typeOf(JSContext *cx, JSObject *proxy)
 {
     JS_ASSERT(OperationInProgress(cx, proxy));
     return proxy->isFunctionProxy() ? JSTYPE_FUNCTION : JSTYPE_OBJECT;
 }
 
 bool
-ProxyHandler::classPropertyIs(JSContext *cx, JSObject *proxy, ESClassValue classValue)
+ProxyHandler::objectClassIs(JSObject *proxy, ESClassValue classValue, JSContext *cx)
 {
     JS_ASSERT(OperationInProgress(cx, proxy));
     return false;
 }
 
 void
 ProxyHandler::finalize(JSContext *cx, JSObject *proxy)
 {
@@ -869,16 +869,24 @@ JSType
 Proxy::typeOf(JSContext *cx, JSObject *proxy)
 {
     // FIXME: API doesn't allow us to report error (bug 618906).
     JS_CHECK_RECURSION(cx, return JSTYPE_OBJECT);
     AutoPendingProxyOperation pending(cx, proxy);
     return proxy->getProxyHandler()->typeOf(cx, proxy);
 }
 
+bool
+Proxy::objectClassIs(JSObject *proxy, ESClassValue classValue, JSContext *cx)
+{
+    JS_CHECK_RECURSION(cx, JS_NOT_REACHED("cannot reenter"));
+    AutoPendingProxyOperation pending(cx, proxy);
+    return proxy->getProxyHandler()->objectClassIs(proxy, classValue, cx);
+}
+
 JSString *
 Proxy::obj_toString(JSContext *cx, JSObject *proxy)
 {
     JS_CHECK_RECURSION(cx, return NULL);
     AutoPendingProxyOperation pending(cx, proxy);
     return proxy->getProxyHandler()->obj_toString(cx, proxy);
 }
 
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -77,17 +77,17 @@ class JS_FRIEND_API(ProxyHandler) {
     virtual bool iterate(JSContext *cx, JSObject *proxy, uintN flags, Value *vp);
 
     /* Spidermonkey extensions. */
     virtual bool call(JSContext *cx, JSObject *proxy, uintN argc, Value *vp);
     virtual bool construct(JSContext *cx, JSObject *proxy, uintN argc, Value *argv, Value *rval);
     virtual bool nativeCall(JSContext *cx, JSObject *proxy, Class *clasp, Native native, CallArgs args);
     virtual bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp);
     virtual JSType typeOf(JSContext *cx, JSObject *proxy);
-    virtual bool classPropertyIs(JSContext *cx, JSObject *obj, ESClassValue classValue);
+    virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
     virtual JSString *obj_toString(JSContext *cx, JSObject *proxy);
     virtual JSString *fun_toString(JSContext *cx, JSObject *proxy, uintN indent);
     virtual bool defaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
     virtual void finalize(JSContext *cx, JSObject *proxy);
     virtual void trace(JSTracer *trc, JSObject *proxy);
 
     virtual bool isOuterWindow() {
         return false;
@@ -126,16 +126,17 @@ class Proxy {
     static bool iterate(JSContext *cx, JSObject *proxy, uintN flags, Value *vp);
 
     /* Spidermonkey extensions. */
     static bool call(JSContext *cx, JSObject *proxy, uintN argc, Value *vp);
     static bool construct(JSContext *cx, JSObject *proxy, uintN argc, Value *argv, Value *rval);
     static bool nativeCall(JSContext *cx, JSObject *proxy, Class *clasp, Native native, CallArgs args);
     static bool hasInstance(JSContext *cx, JSObject *proxy, const Value *vp, bool *bp);
     static JSType typeOf(JSContext *cx, JSObject *proxy);
+    static bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
     static JSString *obj_toString(JSContext *cx, JSObject *proxy);
     static JSString *fun_toString(JSContext *cx, JSObject *proxy, uintN indent);
     static bool defaultValue(JSContext *cx, JSObject *obj, JSType hint, Value *vp);
 };
 
 /* Shared between object and function proxies. */
 const uint32 JSSLOT_PROXY_HANDLER = 0;
 const uint32 JSSLOT_PROXY_PRIVATE = 1;
--- a/js/src/jswrapper.cpp
+++ b/js/src/jswrapper.cpp
@@ -287,17 +287,17 @@ Wrapper::hasInstance(JSContext *cx, JSOb
 
 JSType
 Wrapper::typeOf(JSContext *cx, JSObject *wrapper)
 {
     return TypeOfValue(cx, ObjectValue(*wrappedObject(wrapper)));
 }
 
 bool
-Wrapper::classPropertyIs(JSContext *cx, JSObject *wrapper, ESClassValue classValue)
+Wrapper::objectClassIs(JSObject *wrapper, ESClassValue classValue, JSContext *cx)
 {
     return ObjectClassIs(*wrappedObject(wrapper), classValue, cx);
 }
 
 JSString *
 Wrapper::obj_toString(JSContext *cx, JSObject *wrapper)
 {
     bool status;
--- a/js/src/jswrapper.h
+++ b/js/src/jswrapper.h
@@ -82,17 +82,17 @@ class JS_FRIEND_API(Wrapper) : public Pr
     virtual bool iterate(JSContext *cx, JSObject *wrapper, uintN flags, Value *vp);
 
     /* Spidermonkey extensions. */
     virtual bool call(JSContext *cx, JSObject *wrapper, uintN argc, Value *vp);
     virtual bool construct(JSContext *cx, JSObject *wrapper, uintN argc, Value *argv, Value *rval);
     virtual bool nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args);
     virtual bool hasInstance(JSContext *cx, JSObject *wrapper, const Value *vp, bool *bp);
     virtual JSType typeOf(JSContext *cx, JSObject *proxy);
-    virtual bool classPropertyIs(JSContext *cx, JSObject *obj, ESClassValue classValue);
+    virtual bool objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx);
     virtual JSString *obj_toString(JSContext *cx, JSObject *wrapper);
     virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent);
     virtual bool defaultValue(JSContext *cx, JSObject *wrapper, JSType hint, Value *vp);
 
     virtual void trace(JSTracer *trc, JSObject *wrapper);
 
     /* Policy enforcement traps. */
     enum Action { GET, SET, CALL };