Rename JSNoopProxyHandler to JSWrapper and move it into jswrapper.[h|cpp] (568731, r=cdleary).
authorAndreas Gal <gal@mozilla.com>
Thu, 03 Jun 2010 15:27:29 -0700
changeset 43264 caf9170f297109d11b66627dc4e6f95b1ae9fcee
parent 43263 12dab806d2c509e08f0097884d2cd3f07e2c7b3f
child 43265 d07c78d085ced76f30d582a2bcb7925f3f78ebc3
push idunknown
push userunknown
push dateunknown
reviewerscdleary
bugs568731
milestone1.9.3a5pre
Rename JSNoopProxyHandler to JSWrapper and move it into jswrapper.[h|cpp] (568731, r=cdleary).
js/src/Makefile.in
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jswrapper.cpp
js/src/jswrapper.h
js/src/shell/js.cpp
--- a/js/src/Makefile.in
+++ b/js/src/Makefile.in
@@ -160,16 +160,17 @@ CPPSRCS		= \
 		jsregexp.cpp \
 		jsscan.cpp \
 		jsscope.cpp \
 		jsscript.cpp \
 		jsstr.cpp \
 		jstask.cpp \
 		jstypedarray.cpp \
 		jsutil.cpp \
+		jswrapper.cpp \
 		jsxdrapi.cpp \
 		jsxml.cpp \
 		prmjtime.cpp \
 		$(NULL)
 
 ifdef HAVE_DTRACE
 CPPSRCS 	+= \
 		jsdtracef.cpp
@@ -229,16 +230,17 @@ INSTALLED_HEADERS = \
 		jstracer.h \
 		jstypedarray.h \
 		jstypes.h \
 		jsutil.h \
 		jsvector.h \
 		jstl.h \
 		jshashtable.h \
 		jsversion.h \
+		jswrapper.h \
 		jsxdrapi.h \
 		jsxml.h \
 		prmjtime.h \
 		$(NULL)
 
 ifdef ENABLE_TRACEJIT
 VPATH		+= $(srcdir)/nanojit
 
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -185,143 +185,16 @@ JSProxyHandler::finalize(JSContext *cx, 
 {
 }
 
 void
 JSProxyHandler::trace(JSTracer *trc, JSObject *proxy)
 {
 }
 
-JSNoopProxyHandler::JSNoopProxyHandler(JSObject *obj) : mWrappedObject(obj)
-{
-}
-
-JSNoopProxyHandler::~JSNoopProxyHandler()
-{
-}
-
-bool
-JSNoopProxyHandler::getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
-                                          JSPropertyDescriptor *desc)
-{
-    JSObject *wobj = wrappedObject(proxy);
-    return JS_GetPropertyDescriptorById(cx, wobj, id, JSRESOLVE_QUALIFIED, desc);
-}
-
-bool
-JSNoopProxyHandler::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
-                                             JSPropertyDescriptor *desc)
-{
-    return JS_GetPropertyDescriptorById(cx, wrappedObject(proxy), id, JSRESOLVE_QUALIFIED, desc);
-}
-
-bool
-JSNoopProxyHandler::defineProperty(JSContext *cx, JSObject *proxy, jsid id,
-                                   JSPropertyDescriptor *desc)
-{
-    return JS_DefinePropertyById(cx, wrappedObject(proxy), id, desc->value,
-                                 desc->getter, desc->setter, desc->attrs);
-}
-
-bool
-JSNoopProxyHandler::getOwnPropertyNames(JSContext *cx, JSObject *proxy, JSIdArray **idap)
-{
-    return GetPropertyNames(cx, wrappedObject(proxy), JSITER_OWNONLY | JSITER_HIDDEN, idap);
-}
-
-bool
-JSNoopProxyHandler::delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
-{
-    AutoValueRooter tvr(cx);
-    if (!JS_DeletePropertyById2(cx, wrappedObject(proxy), id, tvr.addr()))
-        return false;
-    *bp = js_ValueToBoolean(tvr.value());
-    return true;
-}
-
-bool
-JSNoopProxyHandler::enumerate(JSContext *cx, JSObject *proxy, JSIdArray **idap)
-{
-    return GetPropertyNames(cx, wrappedObject(proxy), 0, idap);
-}
-
-bool
-JSNoopProxyHandler::fix(JSContext *cx, JSObject *proxy, jsval *vp)
-{
-    *vp = JSVAL_VOID;
-    return true;
-}
-
-bool
-JSNoopProxyHandler::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
-{
-    JSBool found;
-    if (!JS_HasPropertyById(cx, wrappedObject(proxy), id, &found))
-        return false;
-    *bp = !!found;
-    return true;
-}
-
-bool
-JSNoopProxyHandler::hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
-{
-    JSPropertyDescriptor desc;
-    JSObject *wobj = wrappedObject(proxy);
-    if (!JS_GetPropertyDescriptorById(cx, wobj, id, JSRESOLVE_QUALIFIED, &desc))
-        return false;
-    *bp = (desc.obj == wobj);
-    return true;
-}
-
-bool
-JSNoopProxyHandler::get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, jsval *vp)
-{
-    return JS_GetPropertyById(cx, wrappedObject(proxy), id, vp);
-}
-
-bool
-JSNoopProxyHandler::set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, jsval *vp)
-{
-    return JS_SetPropertyById(cx, wrappedObject(proxy), id, vp);
-}
-
-bool
-JSNoopProxyHandler::enumerateOwn(JSContext *cx, JSObject *proxy, JSIdArray **idap)
-{
-    return GetPropertyNames(cx, wrappedObject(proxy), JSITER_OWNONLY, idap);
-}
-
-bool
-JSNoopProxyHandler::iterate(JSContext *cx, JSObject *proxy, uintN flags, jsval *vp)
-{
-    return GetIterator(cx, wrappedObject(proxy), flags, vp);
-}
-
-void
-JSNoopProxyHandler::finalize(JSContext *cx, JSObject *proxy)
-{
-    if (mWrappedObject)
-        delete this;
-}
-
-void
-JSNoopProxyHandler::trace(JSTracer *trc, JSObject *proxy)
-{
-    if (mWrappedObject)
-        JS_CALL_OBJECT_TRACER(trc, mWrappedObject, "wrappedObject");
-}
-
-const void *
-JSNoopProxyHandler::family()
-{
-    return &singleton;
-}
-
-JSNoopProxyHandler JSNoopProxyHandler::singleton(NULL);
-
 static bool
 GetTrap(JSContext *cx, JSObject *handler, JSAtom *atom, jsval *fvalp)
 {
     return handler->getProperty(cx, ATOM_TO_JSID(atom), fvalp);
 }
 
 static bool
 TryHandlerTrap(JSContext *cx, JSObject *proxy, bool ok = true)
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -73,65 +73,16 @@ class JSProxyHandler {
     virtual bool iterate(JSContext *cx, JSObject *proxy, uintN flags, jsval *vp);
 
     /* Spidermonkey extensions. */
     virtual void finalize(JSContext *cx, JSObject *proxy);
     virtual void trace(JSTracer *trc, JSObject *proxy);
     virtual const void *family() = 0;
 };
 
-/* No-op wrapper handler base class. */
-class JSNoopProxyHandler {
-    JSObject *mWrappedObject;
-
-  protected:
-    JS_FRIEND_API(JSNoopProxyHandler(JSObject *));
-
-  public:
-    JS_FRIEND_API(virtual ~JSNoopProxyHandler());
-
-    /* ES5 Harmony fundamental proxy traps. */
-    virtual JS_FRIEND_API(bool) getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
-                                                      JSPropertyDescriptor *desc);
-    virtual JS_FRIEND_API(bool) getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
-                                                         JSPropertyDescriptor *desc);
-    virtual JS_FRIEND_API(bool) defineProperty(JSContext *cx, JSObject *proxy, jsid id,
-                                               JSPropertyDescriptor *desc);
-    virtual JS_FRIEND_API(bool) getOwnPropertyNames(JSContext *cx, JSObject *proxy,
-                                                    JSIdArray **idap);
-    virtual JS_FRIEND_API(bool) delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
-    virtual JS_FRIEND_API(bool) enumerate(JSContext *cx, JSObject *proxy, JSIdArray **idap);
-    virtual JS_FRIEND_API(bool) fix(JSContext *cx, JSObject *proxy, jsval *vp);
-
-    /* ES5 Harmony derived proxy traps. */
-    virtual JS_FRIEND_API(bool) has(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
-    virtual JS_FRIEND_API(bool) hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
-    virtual JS_FRIEND_API(bool) get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id,
-                                    jsval *vp);
-    virtual JS_FRIEND_API(bool) set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id,
-                                    jsval *vp);
-    virtual JS_FRIEND_API(bool) enumerateOwn(JSContext *cx, JSObject *proxy, JSIdArray **idap);
-    virtual JS_FRIEND_API(bool) iterate(JSContext *cx, JSObject *proxy, uintN flags, jsval *vp);
-
-    /* Spidermonkey extensions. */
-    virtual JS_FRIEND_API(void) finalize(JSContext *cx, JSObject *proxy);
-    virtual JS_FRIEND_API(void) trace(JSTracer *trc, JSObject *proxy);
-    virtual JS_FRIEND_API(const void *) family();
-
-    static JSNoopProxyHandler singleton;
-
-    template <class T>
-    static JSObject *wrap(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent,
-                          JSString *className);
-
-    inline JSObject *wrappedObject(JSObject *proxy) {
-        return mWrappedObject ? mWrappedObject : JSVAL_TO_OBJECT(proxy->getProxyPrivate());
-    }
-};
-
 /* Dispatch point for handlers that executes the appropriate C++ or scripted traps. */
 class JSProxy {
   public:
     /* ES5 Harmony fundamental proxy traps. */
     static bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
                                       JSPropertyDescriptor *desc);
     static bool getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, jsval *vp);
     static bool getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
@@ -220,38 +171,16 @@ NewFunctionProxy(JSContext *cx, jsval ha
                  JSObject *call, JSObject *construct);
 
 JS_FRIEND_API(JSBool)
 GetProxyObjectClass(JSContext *cx, JSObject *proxy, const char **namep);
 
 JS_FRIEND_API(JSBool)
 FixProxy(JSContext *cx, JSObject *proxy, JSBool *bp);
 
-template <class T>
-JSObject *
-JSNoopProxyHandler::wrap(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent,
-                         JSString *className)
-{
-    if (obj->isCallable()) {
-        JSNoopProxyHandler *handler = new T(obj);
-        if (!handler)
-            return NULL;
-        JSObject *wrapper = NewFunctionProxy(cx, PRIVATE_TO_JSVAL(handler), proto, parent,
-                                             obj, NULL);
-        if (!wrapper)
-            delete handler;
-        return wrapper;
-    }
-    JSObject *wrapper = NewObjectProxy(cx, PRIVATE_TO_JSVAL(&T::singleton), proto, parent,
-                                       className);
-    if (wrapper)
-        wrapper->setProxyPrivate(OBJECT_TO_JSVAL(obj));
-    return wrapper;
-}
-
 }
 
 JS_BEGIN_EXTERN_C
 
 extern JSClass js_ProxyClass;
 
 extern JS_FRIEND_API(JSObject *)
 js_InitProxyClass(JSContext *cx, JSObject *obj);
new file mode 100644
--- /dev/null
+++ b/js/src/jswrapper.cpp
@@ -0,0 +1,199 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=4 sw=4 et tw=99:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
+ * May 28, 2008.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Andreas Gal <gal@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "jsapi.h"
+#include "jscntxt.h"
+#include "jsiter.h"
+#include "jsnum.h"
+#include "jswrapper.h"
+
+#include "jsobjinlines.h"
+
+using namespace js;
+
+JSWrapper::JSWrapper(JSObject *obj) : mWrappedObject(obj)
+{
+}
+
+JSWrapper::~JSWrapper()
+{
+}
+
+bool
+JSWrapper::getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
+                                          JSPropertyDescriptor *desc)
+{
+    JSObject *wobj = wrappedObject(proxy);
+    return JS_GetPropertyDescriptorById(cx, wobj, id, JSRESOLVE_QUALIFIED, desc);
+}
+
+bool
+JSWrapper::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
+                                             JSPropertyDescriptor *desc)
+{
+    return JS_GetPropertyDescriptorById(cx, wrappedObject(proxy), id, JSRESOLVE_QUALIFIED, desc);
+}
+
+bool
+JSWrapper::defineProperty(JSContext *cx, JSObject *proxy, jsid id,
+                                   JSPropertyDescriptor *desc)
+{
+    return JS_DefinePropertyById(cx, wrappedObject(proxy), id, desc->value,
+                                 desc->getter, desc->setter, desc->attrs);
+}
+
+bool
+JSWrapper::getOwnPropertyNames(JSContext *cx, JSObject *proxy, JSIdArray **idap)
+{
+    return GetPropertyNames(cx, wrappedObject(proxy), JSITER_OWNONLY | JSITER_HIDDEN, idap);
+}
+
+bool
+JSWrapper::delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
+{
+    AutoValueRooter tvr(cx);
+    if (!JS_DeletePropertyById2(cx, wrappedObject(proxy), id, tvr.addr()))
+        return false;
+    *bp = js_ValueToBoolean(tvr.value());
+    return true;
+}
+
+bool
+JSWrapper::enumerate(JSContext *cx, JSObject *proxy, JSIdArray **idap)
+{
+    return GetPropertyNames(cx, wrappedObject(proxy), 0, idap);
+}
+
+bool
+JSWrapper::fix(JSContext *cx, JSObject *proxy, jsval *vp)
+{
+    *vp = JSVAL_VOID;
+    return true;
+}
+
+bool
+JSWrapper::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
+{
+    JSBool found;
+    if (!JS_HasPropertyById(cx, wrappedObject(proxy), id, &found))
+        return false;
+    *bp = !!found;
+    return true;
+}
+
+bool
+JSWrapper::hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
+{
+    JSPropertyDescriptor desc;
+    JSObject *wobj = wrappedObject(proxy);
+    if (!JS_GetPropertyDescriptorById(cx, wobj, id, JSRESOLVE_QUALIFIED, &desc))
+        return false;
+    *bp = (desc.obj == wobj);
+    return true;
+}
+
+bool
+JSWrapper::get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, jsval *vp)
+{
+    return JS_GetPropertyById(cx, wrappedObject(proxy), id, vp);
+}
+
+bool
+JSWrapper::set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, jsval *vp)
+{
+    return JS_SetPropertyById(cx, wrappedObject(proxy), id, vp);
+}
+
+bool
+JSWrapper::enumerateOwn(JSContext *cx, JSObject *proxy, JSIdArray **idap)
+{
+    return GetPropertyNames(cx, wrappedObject(proxy), JSITER_OWNONLY, idap);
+}
+
+bool
+JSWrapper::iterate(JSContext *cx, JSObject *proxy, uintN flags, jsval *vp)
+{
+    return GetIterator(cx, wrappedObject(proxy), flags, vp);
+}
+
+void
+JSWrapper::finalize(JSContext *cx, JSObject *proxy)
+{
+    if (mWrappedObject)
+        delete this;
+}
+
+void
+JSWrapper::trace(JSTracer *trc, JSObject *proxy)
+{
+    if (mWrappedObject)
+        JS_CALL_OBJECT_TRACER(trc, mWrappedObject, "wrappedObject");
+}
+
+const void *
+JSWrapper::family()
+{
+    return &singleton;
+}
+
+JSWrapper JSWrapper::singleton(NULL);
+
+JSObject *
+JSWrapper::wrap(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent, JSString *className)
+{
+    JSObject *wobj;
+    if (obj->isCallable()) {
+        JSWrapper *handler = new JSWrapper(obj);
+        if (!handler)
+            return NULL;
+        wobj = NewFunctionProxy(cx, PRIVATE_TO_JSVAL(handler), proto, parent, obj, NULL);
+        if (!wobj) {
+            delete handler;
+            return NULL;
+        }
+    } else {
+        wobj = NewObjectProxy(cx, PRIVATE_TO_JSVAL(&singleton), proto, parent, className);
+        if (!wobj)
+            return NULL;
+        wobj->setProxyPrivate(OBJECT_TO_JSVAL(obj));
+    }
+    return wobj;
+}
new file mode 100644
--- /dev/null
+++ b/js/src/jswrapper.h
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=4 sw=4 et tw=99:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
+ * May 28, 2008.
+ *
+ * The Initial Developer of the Original Code is
+ *   Mozilla Foundation
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Andreas Gal <gal@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef jswrapper_h___
+#define jswrapper_h___
+
+#include "jsapi.h"
+#include "jsproxy.h"
+
+namespace js {
+
+/* No-op wrapper handler base class. */
+class JSWrapper : public JSProxyHandler {
+    JSObject *mWrappedObject;
+
+    JS_FRIEND_API(JSWrapper(JSObject *));
+
+  public:
+    JS_FRIEND_API(virtual ~JSWrapper());
+
+    /* ES5 Harmony fundamental proxy traps. */
+    virtual JS_FRIEND_API(bool) getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
+                                                      JSPropertyDescriptor *desc);
+    virtual JS_FRIEND_API(bool) getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id,
+                                                         JSPropertyDescriptor *desc);
+    virtual JS_FRIEND_API(bool) defineProperty(JSContext *cx, JSObject *proxy, jsid id,
+                                               JSPropertyDescriptor *desc);
+    virtual JS_FRIEND_API(bool) getOwnPropertyNames(JSContext *cx, JSObject *proxy,
+                                                    JSIdArray **idap);
+    virtual JS_FRIEND_API(bool) delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
+    virtual JS_FRIEND_API(bool) enumerate(JSContext *cx, JSObject *proxy, JSIdArray **idap);
+    virtual JS_FRIEND_API(bool) fix(JSContext *cx, JSObject *proxy, jsval *vp);
+
+    /* ES5 Harmony derived proxy traps. */
+    virtual JS_FRIEND_API(bool) has(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
+    virtual JS_FRIEND_API(bool) hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp);
+    virtual JS_FRIEND_API(bool) get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id,
+                                    jsval *vp);
+    virtual JS_FRIEND_API(bool) set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id,
+                                    jsval *vp);
+    virtual JS_FRIEND_API(bool) enumerateOwn(JSContext *cx, JSObject *proxy, JSIdArray **idap);
+    virtual JS_FRIEND_API(bool) iterate(JSContext *cx, JSObject *proxy, uintN flags, jsval *vp);
+
+    /* Spidermonkey extensions. */
+    virtual JS_FRIEND_API(void) finalize(JSContext *cx, JSObject *proxy);
+    virtual JS_FRIEND_API(void) trace(JSTracer *trc, JSObject *proxy);
+    virtual JS_FRIEND_API(const void *) family();
+
+    static JS_FRIEND_API(JSWrapper) singleton;
+
+    static JS_FRIEND_API(JSObject *) wrap(JSContext *cx, JSObject *obj,
+                                          JSObject *proto, JSObject *parent,
+                                          JSString *className);
+
+    inline JSObject *wrappedObject(JSObject *proxy) {
+        return mWrappedObject ? mWrappedObject : JSVAL_TO_OBJECT(proxy->getProxyPrivate());
+    }
+};
+
+}
+
+#endif
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -48,17 +48,17 @@
 #include <string.h>
 #include <signal.h>
 #include <locale.h>
 #include "jstypes.h"
 #include "jsstdint.h"
 #include "jsarena.h"
 #include "jsutil.h"
 #include "jsprf.h"
-#include "jsproxy.h"
+#include "jswrapper.h"
 #include "jsapi.h"
 #include "jsarray.h"
 #include "jsatom.h"
 #include "jsbuiltins.h"
 #include "jscntxt.h"
 #include "jsdate.h"
 #include "jsdbgapi.h"
 #include "jsemit.h"
@@ -3842,17 +3842,17 @@ JSBool
 Wrap(JSContext *cx, uintN argc, jsval *vp)
 {
     jsval v = argc > 0 ? JS_ARGV(cx, vp)[0] : JSVAL_VOID;
     if (JSVAL_IS_PRIMITIVE(v)) {
         JS_SET_RVAL(cx, vp, v);
         return true;
     }
 
-    JSObject *wrapped = JSNoopProxyHandler::wrap<JSNoopProxyHandler>(cx, JSVAL_TO_OBJECT(v), NULL, NULL, NULL);
+    JSObject *wrapped = JSWrapper::wrap(cx, JSVAL_TO_OBJECT(v), NULL, NULL, NULL);
     if (!wrapped)
         return false;
 
     JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(wrapped));
     return true;
 }
 
 /* We use a mix of JS_FS and JS_FN to test both kinds of natives. */