Bug 648801 (new DOM list bindings) - Stop using nsDOMClassInfo's jsids in new DOM bindings. r=bz/jst/mrbkap.
authorPeter Van der Beken <peterv@propagandism.org>
Tue, 26 Jul 2011 11:51:14 +0200
changeset 79082 ea78bc0b06ff8851e3e94d264709dcf9183a8d90
parent 79081 9c65c03b412ae95f7cf526539d9048b03bb4a1ec
child 79083 53cb5c81ba843d7098d1aacf7b917e104d4cf4cc
push idunknown
push userunknown
push dateunknown
reviewersbz, jst, mrbkap
bugs648801
milestone10.0a1
Bug 648801 (new DOM list bindings) - Stop using nsDOMClassInfo's jsids in new DOM bindings. r=bz/jst/mrbkap.
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
js/src/xpconnect/src/dombindings.cpp
js/src/xpconnect/src/xpcjsruntime.cpp
js/src/xpconnect/src/xpcpublic.h
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -1568,17 +1568,16 @@ bool nsDOMClassInfo::sIsInitialized = fa
 bool nsDOMClassInfo::sDisableDocumentAllSupport = false;
 bool nsDOMClassInfo::sDisableGlobalScopePollutionSupport = false;
 
 
 jsid nsDOMClassInfo::sParent_id          = JSID_VOID;
 jsid nsDOMClassInfo::sScrollbars_id      = JSID_VOID;
 jsid nsDOMClassInfo::sLocation_id        = JSID_VOID;
 jsid nsDOMClassInfo::sConstructor_id     = JSID_VOID;
-jsid nsDOMClassInfo::sPrototype_id       = JSID_VOID;
 jsid nsDOMClassInfo::s_content_id        = JSID_VOID;
 jsid nsDOMClassInfo::sContent_id         = JSID_VOID;
 jsid nsDOMClassInfo::sMenubar_id         = JSID_VOID;
 jsid nsDOMClassInfo::sToolbar_id         = JSID_VOID;
 jsid nsDOMClassInfo::sLocationbar_id     = JSID_VOID;
 jsid nsDOMClassInfo::sPersonalbar_id     = JSID_VOID;
 jsid nsDOMClassInfo::sStatusbar_id       = JSID_VOID;
 jsid nsDOMClassInfo::sDialogArguments_id = JSID_VOID;
@@ -1832,17 +1831,16 @@ nsDOMClassInfo::DefineStaticJSVals(JSCon
       return NS_ERROR_OUT_OF_MEMORY;
 
   JSAutoRequest ar(cx);
 
   SET_JSID_TO_STRING(sParent_id,          cx, "parent");
   SET_JSID_TO_STRING(sScrollbars_id,      cx, "scrollbars");
   SET_JSID_TO_STRING(sLocation_id,        cx, "location");
   SET_JSID_TO_STRING(sConstructor_id,     cx, "constructor");
-  SET_JSID_TO_STRING(sPrototype_id,       cx, "prototype");
   SET_JSID_TO_STRING(s_content_id,        cx, "_content");
   SET_JSID_TO_STRING(sContent_id,         cx, "content");
   SET_JSID_TO_STRING(sMenubar_id,         cx, "menubar");
   SET_JSID_TO_STRING(sToolbar_id,         cx, "toolbar");
   SET_JSID_TO_STRING(sLocationbar_id,     cx, "locationbar");
   SET_JSID_TO_STRING(sPersonalbar_id,     cx, "personalbar");
   SET_JSID_TO_STRING(sStatusbar_id,       cx, "statusbar");
   SET_JSID_TO_STRING(sDialogArguments_id, cx, "dialogArguments");
@@ -4815,17 +4813,16 @@ nsDOMClassInfo::ShutDown()
       NS_IF_RELEASE(sClassInfoData[i].mCachedClassInfo);
     }
   }
 
   sParent_id          = JSID_VOID;
   sScrollbars_id      = JSID_VOID;
   sLocation_id        = JSID_VOID;
   sConstructor_id     = JSID_VOID;
-  sPrototype_id       = JSID_VOID;
   s_content_id        = JSID_VOID;
   sContent_id         = JSID_VOID;
   sMenubar_id         = JSID_VOID;
   sToolbar_id         = JSID_VOID;
   sLocationbar_id     = JSID_VOID;
   sPersonalbar_id     = JSID_VOID;
   sStatusbar_id       = JSID_VOID;
   sDialogArguments_id = JSID_VOID;
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -249,17 +249,16 @@ protected:
   static bool sDisableDocumentAllSupport;
   static bool sDisableGlobalScopePollutionSupport;
 
 public:
   static jsid sParent_id;
   static jsid sScrollbars_id;
   static jsid sLocation_id;
   static jsid sConstructor_id;
-  static jsid sPrototype_id;
   static jsid s_content_id;
   static jsid sContent_id;
   static jsid sMenubar_id;
   static jsid sToolbar_id;
   static jsid sLocationbar_id;
   static jsid sPersonalbar_id;
   static jsid sStatusbar_id;
   static jsid sDialogArguments_id;
--- a/js/src/xpconnect/src/dombindings.cpp
+++ b/js/src/xpconnect/src/dombindings.cpp
@@ -37,29 +37,60 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "dombindings.h"
 #include "xpcprivate.h"
 #include "xpcquickstubs.h"
 #include "XPCWrapper.h"
 #include "WrapperFactory.h"
-
-#include "nsIDOMNode.h"
-
 #include "nsDOMClassInfo.h"
 #include "nsGlobalWindow.h"
 #include "jsiter.h"
 #include "nsWrapperCacheInlines.h"
 
 using namespace js;
 
 namespace xpc {
 namespace dom {
 
+
+static jsid s_constructor_id = JSID_VOID;
+static jsid s_prototype_id = JSID_VOID;
+
+static jsid s_length_id = JSID_VOID;
+static jsid s_item_id = JSID_VOID;
+static jsid s_namedItem_id = JSID_VOID;
+
+bool
+DefineStaticJSVal(JSContext *cx, jsid &id, const char *string)
+{
+    if (JSString *str = ::JS_InternString(cx, string)) {
+        id = INTERNED_STRING_TO_JSID(cx, str);
+        return true;
+    }
+    return false;
+}
+
+#define SET_JSID_TO_STRING(_cx, _string)                                      \
+    DefineStaticJSVal(_cx, s_##_string##_id, #_string)
+
+bool
+DefineStaticJSVals(JSContext *cx)
+{
+    JSAutoRequest ar(cx);
+
+    return SET_JSID_TO_STRING(cx, constructor) &&
+           SET_JSID_TO_STRING(cx, prototype) &&
+           SET_JSID_TO_STRING(cx, length) &&
+           SET_JSID_TO_STRING(cx, item) &&
+           SET_JSID_TO_STRING(cx, namedItem);
+}
+
+
 int HandlerFamily;
 
 
 JSBool
 Throw(JSContext *cx, nsresult rv)
 {
     XPCThrower::Throw(rv, cx);
     return JS_FALSE;
@@ -171,17 +202,17 @@ Class NodeList<nsINodeList>::sInterfaceC
     NULL,                   /* call */
     NULL,                   /* construct */
     NULL,                   /* xdrObject */
     interface_hasInstance
 };
 
 template<>
 NodeList<nsINodeList>::Methods NodeList<nsINodeList>::sProtoMethods[] = {
-    { nsDOMClassInfo::sItem_id, &item, 1 }
+    { s_item_id, &item, 1 }
 };
 
 template<>
 Class NodeList<nsIHTMLCollection>::sInterfaceClass = {
     "HTMLCollection",
     0,
     JS_PropertyStub,        /* addProperty */
     JS_PropertyStub,        /* delProperty */
@@ -200,18 +231,18 @@ Class NodeList<nsIHTMLCollection>::sInte
 };
 
 template<>
 JSBool
 NodeList<nsIHTMLCollection>::namedItem(JSContext *cx, uintN argc, jsval *vp);
 
 template<>
 NodeList<nsIHTMLCollection>::Methods NodeList<nsIHTMLCollection>::sProtoMethods[] = {
-    { nsDOMClassInfo::sItem_id, &item, 1 },
-    { nsDOMClassInfo::sNamedItem_id, &namedItem, 1 }
+    { s_item_id, &item, 1 },
+    { s_namedItem_id, &namedItem, 1 }
 };
 
 void
 Register(nsDOMClassInfoData *aData)
 {
 #define REGISTER_PROTO(_dom_class, T) \
     aData[eDOMClassInfo_##_dom_class##_id].mDefineDOMInterface = NodeList<T>::getPrototype
 
@@ -401,17 +432,17 @@ NodeList<nsIHTMLCollection>::namedItem(J
     return WrapObject(cx, obj, result, cache, vp);
 }
 
 JSBool
 interface_hasInstance(JSContext *cx, JSObject *obj, const js::Value *vp, JSBool *bp)
 {
     if (vp->isObject()) {
         jsval prototype;
-        if (!JS_GetPropertyById(cx, obj, nsDOMClassInfo::sPrototype_id, &prototype) ||
+        if (!JS_GetPropertyById(cx, obj, s_prototype_id, &prototype) ||
             JSVAL_IS_PRIMITIVE(prototype)) {
             JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL,
                                          JSMSG_THROW_TYPE_ERROR);
             return JS_FALSE;
         }
 
         JSObject *other = &vp->toObject();
         if (instanceIsProxy(other)) {
@@ -470,17 +501,17 @@ NodeList<T>::getPrototype(JSContext *cx,
     JSObject* proto;
     if (!js_GetClassPrototype(cx, global, JSProto_Object, &proto))
         return NULL;
 
     interfacePrototype = JS_NewObject(cx, NULL, proto, global);
     if (!interfacePrototype)
         return NULL;
 
-    if (!JS_DefinePropertyById(cx, interfacePrototype, nsDOMClassInfo::sLength_id,
+    if (!JS_DefinePropertyById(cx, interfacePrototype, s_length_id,
                                JSVAL_VOID, length_getter, NULL,
                                JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_SHARED))
         return NULL;
 
     for (size_t n = 0; n < NS_ARRAY_LENGTH(sProtoMethods); ++n) {
         jsid id = sProtoMethods[n].id;
         JSFunction *fun = JS_NewFunctionById(cx, sProtoMethods[n].native, sProtoMethods[n].nargs,
                                              0, js::GetObjectParent(interfacePrototype), id);
@@ -489,22 +520,22 @@ NodeList<T>::getPrototype(JSContext *cx,
         JSObject *funobj = JS_GetFunctionObject(fun);
         if (!JS_DefinePropertyById(cx, interfacePrototype, id, OBJECT_TO_JSVAL(funobj),
                                    NULL, NULL, JSPROP_ENUMERATE))
             return NULL;
     }
 
     JSObject *interface = JS_NewObject(cx, Jsvalify(&sInterfaceClass), NULL, global);
     if (!interface ||
-        !JS_DefinePropertyById(cx, interface, nsDOMClassInfo::sPrototype_id,
+        !JS_DefinePropertyById(cx, interface, s_prototype_id,
                                OBJECT_TO_JSVAL(interfacePrototype), nsnull, nsnull,
                                JSPROP_PERMANENT | JSPROP_READONLY))
         return NULL;
 
-    if (!JS_DefinePropertyById(cx, interfacePrototype, nsDOMClassInfo::sConstructor_id,
+    if (!JS_DefinePropertyById(cx, interfacePrototype, s_constructor_id,
                                OBJECT_TO_JSVAL(interface), nsnull, nsnull, 0))
         return NULL;
 
     if (!JS_DefineProperty(cx, global, sInterfaceClass.name, OBJECT_TO_JSVAL(interface), NULL,
                            NULL, 0))
         return NULL;
 
     if (!cache.Put(sInterfaceClass.name, interfacePrototype))
@@ -777,17 +808,17 @@ NodeList<T>::has(JSContext *cx, JSObject
     return ProxyHandler::has(cx, proxy, id, bp);
 }
 
 template<class T>
 bool
 NodeList<T>::cacheProtoShape(JSContext *cx, JSObject *proxy, JSObject *proto)
 {
     JSPropertyDescriptor desc;
-    if (!JS_GetPropertyDescriptorById(cx, proto, nsDOMClassInfo::sLength_id, JSRESOLVE_QUALIFIED, &desc))
+    if (!JS_GetPropertyDescriptorById(cx, proto, s_length_id, JSRESOLVE_QUALIFIED, &desc))
         return false;
     if (desc.obj != proto || desc.getter != length_getter)
         return true; // don't cache
 
     for (size_t n = 0; n < NS_ARRAY_LENGTH(sProtoMethods); ++n) {
         jsid id = sProtoMethods[n].id;
         if (!JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, &desc))
             return false;
@@ -820,17 +851,17 @@ NodeList<T>::checkForCacheHit(JSContext 
 }
 
 template<class T>
 bool
 NodeList<T>::resolveNativeName(JSContext *cx, JSObject *proxy, jsid id, PropertyDescriptor *desc)
 {
     JS_ASSERT(WrapperFactory::IsXrayWrapper(proxy));
 
-    if (id == nsDOMClassInfo::sLength_id) {
+    if (id == s_length_id) {
         desc->attrs = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_SHARED;
         desc->obj = proxy;
         desc->setter = nsnull;
         desc->getter = length_getter;
         return true;
     }
 
     for (size_t n = 0; n < NS_ARRAY_LENGTH(sProtoMethods); ++n) {
@@ -885,17 +916,17 @@ NodeList<T>::get(JSContext *cx, JSObject
             return WrapObject(cx, proxy, result, result, vp);
     }
 
     JSObject *proto = js::GetObjectProto(proxy);
     bool hit;
     if (!checkForCacheHit(cx, proxy, receiver, proto, id, vp, &hit))
         return false;
     if (hit) {
-        if (id == nsDOMClassInfo::sLength_id) {
+        if (id == s_length_id) {
             PRUint32 length;
             getNodeList(proxy)->GetLength(&length);
             JS_ASSERT(int32(length) >= 0);
             vp->setInt32(length);
             return true;
         }
         for (size_t n = 0; n < NS_ARRAY_LENGTH(sProtoMethods); ++n) {
             if (id == sProtoMethods[n].id) {
--- a/js/src/xpconnect/src/xpcjsruntime.cpp
+++ b/js/src/xpconnect/src/xpcjsruntime.cpp
@@ -2157,28 +2157,34 @@ XPCJSRuntime::OnJSContextNew(JSContext *
 {
     NS_TIME_FUNCTION;
 
     // if it is our first context then we need to generate our string ids
     JSBool ok = JS_TRUE;
     if(JSID_IS_VOID(mStrIDs[0]))
     {
         JS_SetGCParameterForThread(cx, JSGC_MAX_CODE_CACHE_BYTES, 16 * 1024 * 1024);
-        JSAutoRequest ar(cx);
-        for(uintN i = 0; i < IDX_TOTAL_COUNT; i++)
         {
-            JSString* str = JS_InternString(cx, mStrings[i]);
-            if(!str || !JS_ValueToId(cx, STRING_TO_JSVAL(str), &mStrIDs[i]))
+            // Scope the JSAutoRequest so it goes out of scope before calling
+            // xpc::dom::DefineStaticJSVals.
+            JSAutoRequest ar(cx);
+            for(uintN i = 0; i < IDX_TOTAL_COUNT; i++)
             {
-                mStrIDs[0] = JSID_VOID;
-                ok = JS_FALSE;
-                break;
+                JSString* str = JS_InternString(cx, mStrings[i]);
+                if(!str || !JS_ValueToId(cx, STRING_TO_JSVAL(str), &mStrIDs[i]))
+                {
+                    mStrIDs[0] = JSID_VOID;
+                    ok = JS_FALSE;
+                    break;
+                }
+                mStrJSVals[i] = STRING_TO_JSVAL(str);
             }
-            mStrJSVals[i] = STRING_TO_JSVAL(str);
         }
+
+        ok = xpc::dom::DefineStaticJSVals(cx);
     }
     if (!ok)
         return JS_FALSE;
 
     XPCPerThreadData* tls = XPCPerThreadData::GetData(cx);
     if(!tls)
         return JS_FALSE;
 
--- a/js/src/xpconnect/src/xpcpublic.h
+++ b/js/src/xpconnect/src/xpcpublic.h
@@ -283,16 +283,18 @@ inline bool isExpandoObject(JSObject *ob
 enum {
     JSPROXYSLOT_PROTOSHAPE = 0,
     JSPROXYSLOT_EXPANDO = 1
 };
 
 typedef JSObject*
 (*DefineInterface)(JSContext *cx, XPCWrappedNativeScope *scope, bool *enabled);
 
+extern bool
+DefineStaticJSVals(JSContext *cx);
 void
 Register(nsDOMClassInfoData *aData);
 extern bool
 DefineConstructor(JSContext *cx, JSObject *obj, DefineInterface aDefine,
                   nsresult *aResult);
 
 }
 }