Bug 910823 - Constify static js::Class/JSClass instances. r=waldo
authorDan Gohman <sunfish@google.com>
Wed, 11 Sep 2013 05:49:05 -0700
changeset 159462 03174045ef8d72ab2a0486e656c988bb3644951d
parent 159461 fed748b27845500f2fcf35d8b0fcde767b53d843
child 159463 76c9069bdb56ce4619e8607fc3e5f596291185a4
push id2961
push userlsblakk@mozilla.com
push dateMon, 28 Oct 2013 21:59:28 +0000
treeherdermozilla-beta@73ef4f13486f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswaldo
bugs910823
milestone26.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 910823 - Constify static js::Class/JSClass instances. r=waldo
caps/src/nsScriptSecurityManager.cpp
caps/src/nsSecurityManagerFactory.cpp
content/xbl/src/nsXBLBinding.cpp
content/xbl/src/nsXBLDocumentInfo.cpp
content/xbl/src/nsXBLProtoImplField.cpp
content/xbl/src/nsXBLService.h
content/xul/document/src/nsXULPrototypeDocument.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfo.h
dom/base/nsJSEnvironment.cpp
dom/base/nsJSUtils.cpp
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/Codegen.py
dom/bindings/DOMJSClass.h
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/IDBObjectStore.h
dom/plugins/base/nsJSNPRuntime.cpp
dom/plugins/base/nsJSNPRuntime.h
dom/workers/DOMBindingInlines.h
dom/workers/Events.cpp
dom/workers/File.cpp
dom/workers/Worker.cpp
dom/workers/Worker.h
dom/workers/WorkerScope.cpp
dom/workers/WorkerScope.h
js/jsd/jsd_high.cpp
js/jsd/jsd_xpc.cpp
js/public/CallNonGenericMethod.h
js/public/Class.h
js/src/builtin/Intl.cpp
js/src/builtin/MapObject.cpp
js/src/builtin/MapObject.h
js/src/builtin/Module.cpp
js/src/builtin/Module.h
js/src/builtin/ParallelArray.cpp
js/src/builtin/ParallelArray.h
js/src/builtin/TestingFunctions.cpp
js/src/builtin/TypeRepresentation.cpp
js/src/builtin/TypeRepresentation.h
js/src/builtin/TypedObject.cpp
js/src/builtin/TypedObject.h
js/src/ctypes/CTypes.cpp
js/src/ctypes/Library.cpp
js/src/gc/Marking.cpp
js/src/gc/Nursery.cpp
js/src/gdb/gdb-tests.cpp
js/src/jit/AsmJSModule.cpp
js/src/jit/AsmJSModule.h
js/src/jit/BaselineIC.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/IonCaches.cpp
js/src/jit/IonMacroAssembler.h
js/src/jit/MCallOptimize.cpp
js/src/jit/MIR.cpp
js/src/jsapi-tests/README
js/src/jsapi-tests/testAddPropertyPropcache.cpp
js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
js/src/jsapi-tests/testChromeBuffer.cpp
js/src/jsapi-tests/testClassGetter.cpp
js/src/jsapi-tests/testCustomIterator.cpp
js/src/jsapi-tests/testLookup.cpp
js/src/jsapi-tests/testNewObject.cpp
js/src/jsapi-tests/testObjectEmulatingUndefined.cpp
js/src/jsapi-tests/testOps.cpp
js/src/jsapi-tests/testProfileStrings.cpp
js/src/jsapi-tests/testPropCache.cpp
js/src/jsapi-tests/testResolveRecursion.cpp
js/src/jsapi-tests/tests.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsarray.cpp
js/src/jsbool.cpp
js/src/jscntxt.h
js/src/jsdate.cpp
js/src/jsexn.cpp
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.cpp
js/src/jsfun.h
js/src/jsgc.h
js/src/jsgcinlines.h
js/src/jsinfer.cpp
js/src/jsinfer.h
js/src/jsinferinlines.h
js/src/jsiter.cpp
js/src/jsiter.h
js/src/jsmath.cpp
js/src/jsnum.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/json.cpp
js/src/jsproxy.cpp
js/src/jsproxy.h
js/src/jsscript.cpp
js/src/jsscript.h
js/src/jsstr.cpp
js/src/jsweakmap.cpp
js/src/jsworkers.cpp
js/src/perf/jsperf.cpp
js/src/shell/js.cpp
js/src/vm/ArgumentsObject.cpp
js/src/vm/ArgumentsObject.h
js/src/vm/ArrayObject.h
js/src/vm/BooleanObject.h
js/src/vm/DateObject.h
js/src/vm/Debugger.cpp
js/src/vm/Debugger.h
js/src/vm/ErrorObject.h
js/src/vm/GeneratorObject.h
js/src/vm/GlobalObject.cpp
js/src/vm/GlobalObject.h
js/src/vm/Interpreter.cpp
js/src/vm/NumberObject.h
js/src/vm/ObjectImpl.cpp
js/src/vm/ObjectImpl.h
js/src/vm/OldDebugAPI.cpp
js/src/vm/Probes.h
js/src/vm/ProxyObject.h
js/src/vm/RegExpObject.cpp
js/src/vm/RegExpObject.h
js/src/vm/RegExpStatics.cpp
js/src/vm/RegExpStaticsObject.h
js/src/vm/Runtime-inl.h
js/src/vm/Runtime.h
js/src/vm/ScopeObject.cpp
js/src/vm/ScopeObject.h
js/src/vm/SelfHosting.cpp
js/src/vm/Shape-inl.h
js/src/vm/Shape.cpp
js/src/vm/Shape.h
js/src/vm/StopIterationObject.h
js/src/vm/StringObject.h
js/src/vm/TypedArrayObject.cpp
js/src/vm/TypedArrayObject.h
js/src/vm/WeakMapObject.h
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/shell/xpcshell.cpp
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCCallContext.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCJSContextStack.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCQuickStubs.cpp
js/xpconnect/src/XPCQuickStubs.h
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/XPCWrappedNativeProto.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
js/xpconnect/wrappers/AccessCheck.cpp
js/xpconnect/wrappers/XrayWrapper.cpp
js/xpconnect/wrappers/XrayWrapper.h
netwerk/base/src/ProxyAutoConfig.cpp
startupcache/test/TestStartupCache.cpp
toolkit/components/telemetry/Telemetry.cpp
tools/profiler/SaveProfileTask.cpp
xpcom/base/CycleCollectedJSRuntime.cpp
xpcom/base/CycleCollectedJSRuntime.h
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -1999,17 +1999,17 @@ nsScriptSecurityManager::old_doGetObject
         if (js::IsCallObject(obj)) {
             obj = js::GetObjectParentMaybeScope(obj);
 
             if (!obj)
                 return nullptr;
         }
     }
 
-    js::Class *jsClass = js::GetObjectClass(obj);
+    const js::Class *jsClass = js::GetObjectClass(obj);
 
     do {
         // Note: jsClass is set before this loop, and also at the
         // *end* of this loop.
 
         if (IS_WN_CLASS(jsClass)) {
             result = nsXPConnect::XPConnect()->GetPrincipal(obj,
                                                             aAllowShortCircuit);
--- a/caps/src/nsSecurityManagerFactory.cpp
+++ b/caps/src/nsSecurityManagerFactory.cpp
@@ -76,17 +76,17 @@ nsSecurityNameSet::InitializeNameSet(nsI
     JS::Rooted<JSObject*> obj(cx, global);
     JS::Rooted<JSObject*> proto(cx);
     for (;;) {
         MOZ_ALWAYS_TRUE(JS_GetPrototype(cx, obj, &proto));
         if (!proto)
             break;
         obj = proto;
     }
-    JSClass *objectClass = JS_GetClass(obj);
+    const JSClass *objectClass = JS_GetClass(obj);
 
     JS::Rooted<JS::Value> v(cx);
     if (!JS_GetProperty(cx, global, "netscape", &v))
         return NS_ERROR_FAILURE;
 
     JS::Rooted<JSObject*> securityObj(cx);
     if (v.isObject()) {
         /*
--- a/content/xbl/src/nsXBLBinding.cpp
+++ b/content/xbl/src/nsXBLBinding.cpp
@@ -781,17 +781,17 @@ nsXBLBinding::ChangeDocument(nsIDocument
           for ( ; true; base = proto) { // Will break out on null proto
             if (!JS_GetPrototype(cx, base, &proto)) {
               return;
             }
             if (!proto) {
               break;
             }
 
-            JSClass* clazz = ::JS_GetClass(proto);
+            const JSClass* clazz = ::JS_GetClass(proto);
             if (!clazz ||
                 (~clazz->flags &
                  (JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS)) ||
                 JSCLASS_RESERVED_SLOTS(clazz) != 1 ||
                 clazz->finalize != XBLFinalize) {
               // Clearly not the right class
               continue;
             }
--- a/content/xbl/src/nsXBLDocumentInfo.cpp
+++ b/content/xbl/src/nsXBLDocumentInfo.cpp
@@ -55,17 +55,17 @@ public:
   void Destroy();
   nsIPrincipal* GetPrincipal();
 
   static bool doCheckAccess(JSContext *cx, JS::Handle<JSObject*> obj,
                             JS::Handle<jsid> id, uint32_t accessType);
 
   void ClearGlobalObjectOwner();
 
-  static JSClass gSharedGlobalClass;
+  static const JSClass gSharedGlobalClass;
 
 protected:
   virtual ~nsXBLDocGlobalObject();
 
   JS::Heap<JSObject*> mJSObject;
   nsXBLDocumentInfo* mGlobalObjectOwner; // weak reference
   bool mDestroyed; // Probably not necessary, but let's be safe.
 };
@@ -146,17 +146,17 @@ nsXBLDocGlobalObject_finalize(JSFreeOp *
 static bool
 nsXBLDocGlobalObject_resolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id)
 {
   bool did_resolve = false;
   return JS_ResolveStandardClass(cx, obj, id, &did_resolve);
 }
 
 
-JSClass nsXBLDocGlobalObject::gSharedGlobalClass = {
+const JSClass nsXBLDocGlobalObject::gSharedGlobalClass = {
     "nsXBLPrototypeScript compilation scope",
     JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
     JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0),
     JS_PropertyStub,  JS_DeletePropertyStub,
     nsXBLDocGlobalObject_getProperty, nsXBLDocGlobalObject_setProperty,
     JS_EnumerateStub, nsXBLDocGlobalObject_resolve,
     JS_ConvertStub, nsXBLDocGlobalObject_finalize,
     nsXBLDocGlobalObject_checkAccess, nullptr, nullptr, nullptr,
--- a/content/xbl/src/nsXBLProtoImplField.cpp
+++ b/content/xbl/src/nsXBLProtoImplField.cpp
@@ -111,17 +111,17 @@ ValueHasISupportsPrivate(JS::Handle<JS::
     return false;
   }
 
   const DOMClass* domClass = GetDOMClass(&v.toObject());
   if (domClass) {
     return domClass->mDOMObjectIsISupports;
   }
 
-  JSClass* clasp = ::JS_GetClass(&v.toObject());
+  const JSClass* clasp = ::JS_GetClass(&v.toObject());
   const uint32_t HAS_PRIVATE_NSISUPPORTS =
     JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS;
   return (clasp->flags & HAS_PRIVATE_NSISUPPORTS) == HAS_PRIVATE_NSISUPPORTS;
 }
 
 #ifdef DEBUG
 static bool
 ValueHasISupportsPrivate(JSContext* cx, const JS::Value& aVal)
--- a/content/xbl/src/nsXBLService.h
+++ b/content/xbl/src/nsXBLService.h
@@ -157,19 +157,27 @@ public:
   nsCString& Key() { return mKey; }
   void SetKey(const nsCString& aKey) { mKey = aKey; }
 
   nsrefcnt Hold() { return ++mRefCnt; }
   nsrefcnt Drop() { return --mRefCnt ? mRefCnt : Destroy(); }
   nsrefcnt AddRef() { return Hold(); }
   nsrefcnt Release() { return Drop(); }
 
-  // Downcast from a pointer to JSClass to a pointer to nsXBLJSClass.
+  // Downcast from a pointer to const JSClass to a pointer to non-const
+  // nsXBLJSClass.
+  //
+  // The const_cast is safe because nsXBLJSClass instances are never actually
+  // const. It's necessary because we pass pointers to nsXBLJSClass to code
+  // which uses pointers to const JSClass, and returns them back to us that
+  // way, and we need to convert them back to pointers to non-const
+  // nsXBLJSClass so that we can modify the reference count and add them to
+  // the gClassLRUList list.
   static nsXBLJSClass*
-  fromJSClass(JSClass* c)
+  fromJSClass(const JSClass* c)
   {
-    nsXBLJSClass* x = static_cast<nsXBLJSClass*>(c);
+    nsXBLJSClass* x = const_cast<nsXBLJSClass*>(static_cast<const nsXBLJSClass*>(c));
     MOZ_ASSERT(nsXBLService::getClass(x->mKey) == x);
     return x;
   }
 };
 
 #endif
--- a/content/xul/document/src/nsXULPrototypeDocument.cpp
+++ b/content/xul/document/src/nsXULPrototypeDocument.cpp
@@ -65,17 +65,17 @@ public:
 protected:
     virtual ~nsXULPDGlobalObject();
 
     nsCOMPtr<nsIPrincipal> mCachedPrincipal;
     nsXULPrototypeDocument* mGlobalObjectOwner; // weak reference
     JS::Heap<JSObject*> mJSObject;
     bool mDestroyed; // Probably not necessary, but let's be safe.
 
-    static JSClass gSharedGlobalClass;
+    static const JSClass gSharedGlobalClass;
 };
 
 nsIPrincipal* nsXULPrototypeDocument::gSystemPrincipal;
 nsXULPDGlobalObject* nsXULPrototypeDocument::gSystemGlobal;
 uint32_t nsXULPrototypeDocument::gRefCnt;
 
 
 void
@@ -93,17 +93,17 @@ bool
 nsXULPDGlobalObject_resolve(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id)
 {
     bool did_resolve = false;
 
     return JS_ResolveStandardClass(cx, obj, id, &did_resolve);
 }
 
 
-JSClass nsXULPDGlobalObject::gSharedGlobalClass = {
+const JSClass nsXULPDGlobalObject::gSharedGlobalClass = {
     "nsXULPrototypeScript compilation scope",
     JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS |
     JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(0),
     JS_PropertyStub,  JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, nsXULPDGlobalObject_resolve,  JS_ConvertStub,
     nsXULPDGlobalObject_finalize, nullptr, nullptr, nullptr, nullptr,
     nullptr
 };
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -848,17 +848,17 @@ NS_INTERFACE_MAP_BEGIN(nsDOMClassInfo)
                                     static_cast<nsXPCClassInfo*>(this));
   else
   NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
   NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIClassInfo)
 NS_INTERFACE_MAP_END
 
 
-static JSClass sDOMConstructorProtoClass = {
+static const JSClass sDOMConstructorProtoClass = {
   "DOM Constructor.prototype", 0,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, nullptr
 };
 
 
 static const char *
 CutPrefix(const char *aName) {
@@ -2618,17 +2618,17 @@ nsDOMConstructor::HasInstance(nsIXPConne
   JS::Rooted<JSObject*> dom_obj(cx, v.toObjectOrNull());
   NS_ASSERTION(dom_obj, "nsDOMConstructor::HasInstance couldn't get object");
 
   // This might not be the right object, if there are wrappers. Unwrap if we can.
   JSObject *wrapped_obj = js::CheckedUnwrap(dom_obj, /* stopAtOuter = */ false);
   if (wrapped_obj)
       dom_obj = wrapped_obj;
 
-  JSClass *dom_class = JS_GetClass(dom_obj);
+  const JSClass *dom_class = JS_GetClass(dom_obj);
   if (!dom_class) {
     NS_ERROR("nsDOMConstructor::HasInstance can't get class.");
     return NS_ERROR_UNEXPECTED;
   }
 
   const nsGlobalNameStruct *name_struct;
   nsresult rv = GetNameStruct(NS_ConvertASCIItoUTF16(dom_class->name), &name_struct);
   if (NS_FAILED(rv)) {
@@ -4158,17 +4158,17 @@ nsStringListSH::GetStringAt(nsISupports 
   }
 #endif
   return rv;
 }
 
 
 // HTMLAllCollection
 
-JSClass sHTMLDocumentAllClass = {
+const JSClass sHTMLDocumentAllClass = {
   "HTML document.all class",
   JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS | JSCLASS_NEW_RESOLVE |
   JSCLASS_EMULATES_UNDEFINED | JSCLASS_HAS_RESERVED_SLOTS(1),
   JS_PropertyStub,                                         /* addProperty */
   JS_DeletePropertyStub,                                   /* delProperty */
   nsHTMLDocumentSH::DocumentAllGetProperty,                /* getProperty */
   JS_StrictPropertyStub,                                   /* setProperty */
   JS_EnumerateStub,
--- a/dom/base/nsDOMClassInfo.h
+++ b/dom/base/nsDOMClassInfo.h
@@ -426,17 +426,17 @@ public:
 private:
   // Not implemented, nothing should create an instance of this class.
   static nsIClassInfo *doCreate(nsDOMClassInfoData* aData);
 };
 
 
 // HTMLAllCollection
 
-extern JSClass sHTMLDocumentAllClass;
+extern const JSClass sHTMLDocumentAllClass;
 
 class nsHTMLDocumentSH
 {
 protected:
   static bool GetDocumentAllNodeList(JSContext *cx, JS::Handle<JSObject*> obj,
                                      nsDocument *doc,
                                      nsContentList **nodeList);
 public:
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1119,17 +1119,17 @@ nsJSContext::GetGlobalObject()
     JSObject *inner = JS_ObjectToInnerObject(cx, global);
 
     // If this assertion hits then it means that we have a window object as
     // our global, but we never called CreateOuterObject.
     NS_ASSERTION(inner == global, "Shouldn't be able to innerize here");
   }
 #endif
 
-  JSClass *c = JS_GetClass(global);
+  const JSClass *c = JS_GetClass(global);
 
   // Whenever we end up with globals that are JSCLASS_IS_DOMJSCLASS
   // and have an nsISupports DOM object, we will need to modify this
   // check here.
   MOZ_ASSERT(!(c->flags & JSCLASS_IS_DOMJSCLASS));
   if ((~c->flags) & (JSCLASS_HAS_PRIVATE |
                      JSCLASS_PRIVATE_IS_NSISUPPORTS)) {
     return nullptr;
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -42,17 +42,17 @@ nsJSUtils::GetCallingLocation(JSContext*
   *aLineno = lineno;
 
   return true;
 }
 
 nsIScriptGlobalObject *
 nsJSUtils::GetStaticScriptGlobal(JSObject* aObj)
 {
-  JSClass* clazz;
+  const JSClass* clazz;
   JSObject* glob = aObj; // starting point for search
 
   if (!glob)
     return nullptr;
 
   glob = js::GetGlobalForObjectCrossCompartment(glob);
   NS_ABORT_IF_FALSE(glob, "Infallible returns null");
 
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -323,17 +323,17 @@ InterfaceObjectToString(JSContext* cx, u
   if (!obj) {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_CANT_CONVERT_TO,
                          "null", "object");
     return false;
   }
 
   JS::Value v = js::GetFunctionNativeReserved(callee,
                                               TOSTRING_CLASS_RESERVED_SLOT);
-  JSClass* clasp = static_cast<JSClass*>(JSVAL_TO_PRIVATE(v));
+  const JSClass* clasp = static_cast<const JSClass*>(JSVAL_TO_PRIVATE(v));
 
   v = js::GetFunctionNativeReserved(callee, TOSTRING_NAME_RESERVED_SLOT);
   JSString* jsname = static_cast<JSString*>(JSVAL_TO_STRING(v));
   size_t length;
   const jschar* name = JS_GetInternedStringCharsAndLength(jsname, &length);
 
   if (js::GetObjectJSClass(obj) != clasp) {
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
@@ -397,17 +397,17 @@ DefineConstructor(JSContext* cx, JS::Han
   return alreadyDefined ||
          JS_DefineProperty(cx, global, name, OBJECT_TO_JSVAL(constructor),
                            nullptr, nullptr, 0);
 }
 
 static JSObject*
 CreateInterfaceObject(JSContext* cx, JS::Handle<JSObject*> global,
                       JS::Handle<JSObject*> constructorProto,
-                      JSClass* constructorClass,
+                      const JSClass* constructorClass,
                       const JSNativeHolder* constructorNative,
                       unsigned ctorNargs, const NamedConstructor* namedConstructors,
                       JS::Handle<JSObject*> proto,
                       const NativeProperties* properties,
                       const NativeProperties* chromeOnlyProperties,
                       const char* name, bool defineOnGlobal)
 {
   JS::Rooted<JSObject*> constructor(cx);
@@ -437,17 +437,17 @@ CreateInterfaceObject(JSContext* cx, JS:
     }
 
     JSString *str = ::JS_InternString(cx, name);
     if (!str) {
       return NULL;
     }
     JSObject* toStringObj = JS_GetFunctionObject(toString);
     js::SetFunctionNativeReserved(toStringObj, TOSTRING_CLASS_RESERVED_SLOT,
-                                  PRIVATE_TO_JSVAL(constructorClass));
+                                  PRIVATE_TO_JSVAL(const_cast<JSClass *>(constructorClass)));
 
     js::SetFunctionNativeReserved(toStringObj, TOSTRING_NAME_RESERVED_SLOT,
                                   STRING_TO_JSVAL(str));
 
     if (!JS_DefineProperty(cx, constructor, "length", JS::Int32Value(ctorNargs),
                            nullptr, nullptr, JSPROP_READONLY | JSPROP_PERMANENT)) {
       return NULL;
     }
@@ -538,17 +538,17 @@ DefineWebIDLBindingPropertiesOnXPCProto(
   }
 
   return true;
 }
 
 static JSObject*
 CreateInterfacePrototypeObject(JSContext* cx, JS::Handle<JSObject*> global,
                                JS::Handle<JSObject*> parentProto,
-                               JSClass* protoClass,
+                               const JSClass* protoClass,
                                const NativeProperties* properties,
                                const NativeProperties* chromeOnlyProperties)
 {
   JS::Rooted<JSObject*> ourProto(cx,
     JS_NewObjectWithUniqueType(cx, protoClass, parentProto, global));
   if (!ourProto) {
     return NULL;
   }
@@ -588,19 +588,19 @@ CreateInterfacePrototypeObject(JSContext
   }
 
   return ourProto;
 }
 
 void
 CreateInterfaceObjects(JSContext* cx, JS::Handle<JSObject*> global,
                        JS::Handle<JSObject*> protoProto,
-                       JSClass* protoClass, JS::Heap<JSObject*>* protoCache,
+                       const JSClass* protoClass, JS::Heap<JSObject*>* protoCache,
                        JS::Handle<JSObject*> constructorProto,
-                       JSClass* constructorClass, const JSNativeHolder* constructor,
+                       const JSClass* constructorClass, const JSNativeHolder* constructor,
                        unsigned ctorNargs, const NamedConstructor* namedConstructors,
                        JS::Heap<JSObject*>* constructorCache, const DOMClass* domClass,
                        const NativeProperties* properties,
                        const NativeProperties* chromeOnlyProperties,
                        const char* name, bool defineOnGlobal)
 {
   MOZ_ASSERT(protoClass || constructorClass || constructor,
              "Need at least one class or a constructor!");
@@ -730,17 +730,17 @@ TryPreserveWrapper(JSObject* obj)
 }
 
 // Can only be called with the immediate prototype of the instance object. Can
 // only be called on the prototype of an object known to be a DOM instance.
 bool
 InstanceClassHasProtoAtDepth(JS::Handle<JSObject*> protoObject, uint32_t protoID,
                              uint32_t depth)
 {
-  const DOMClass* domClass = static_cast<DOMClass*>(
+  const DOMClass* domClass = static_cast<const DOMClass*>(
     js::GetReservedSlot(protoObject, DOM_PROTO_INSTANCE_CLASS_SLOT).toPrivate());
   return (uint32_t)domClass->mInterfaceChain[depth] == protoID;
 }
 
 // Only set allowNativeWrapper to false if you really know you need it, if in
 // doubt use true. Setting it to false disables security wrappers.
 bool
 XPCOMObjectToJsval(JSContext* cx, JS::Handle<JSObject*> scope,
@@ -1435,17 +1435,17 @@ AppendNamedPropertyIds(JSContext* cx, JS
   }
 
   return true;
 }
 
 JSObject*
 GetXrayExpandoChain(JSObject* obj)
 {
-  js::Class* clasp = js::GetObjectClass(obj);
+  const js::Class* clasp = js::GetObjectClass(obj);
   JS::Value v;
   if (IsDOMClass(clasp) || IsDOMIfaceAndProtoClass(clasp)) {
     v = js::GetReservedSlot(obj, DOM_XRAY_EXPANDO_SLOT);
   } else if (js::IsProxyClass(clasp)) {
     MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily());
     v = js::GetProxyExtra(obj, JSPROXYSLOT_XRAY_EXPANDO);
   } else {
     MOZ_ASSERT(JS_IsNativeFunction(obj, Constructor));
@@ -1453,17 +1453,17 @@ GetXrayExpandoChain(JSObject* obj)
   }
   return v.isUndefined() ? nullptr : &v.toObject();
 }
 
 void
 SetXrayExpandoChain(JSObject* obj, JSObject* chain)
 {
   JS::Value v = chain ? JS::ObjectValue(*chain) : JSVAL_VOID;
-  js::Class* clasp = js::GetObjectClass(obj);
+  const js::Class* clasp = js::GetObjectClass(obj);
   if (IsDOMClass(clasp) || IsDOMIfaceAndProtoClass(clasp)) {
     js::SetReservedSlot(obj, DOM_XRAY_EXPANDO_SLOT, v);
   } else if (js::IsProxyClass(clasp)) {
     MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily());
     js::SetProxyExtra(obj, JSPROXYSLOT_XRAY_EXPANDO, v);
   } else {
     MOZ_ASSERT(JS_IsNativeFunction(obj, Constructor));
     js::SetFunctionNativeReserved(obj, CONSTRUCTOR_XRAY_EXPANDO_SLOT, v);
@@ -1537,17 +1537,17 @@ NativeToString(JSContext* cx, JS::Handle
         str = toStringResult.toString();
       } else {
         str = nullptr;
       }
     } else {
       if (IsDOMProxy(obj)) {
         str = JS_BasicObjectToString(cx, obj);
       } else {
-        js::Class* clasp = js::GetObjectClass(obj);
+        const js::Class* clasp = js::GetObjectClass(obj);
         if (IsDOMClass(clasp)) {
           str = ConcatJSString(cx, "[object ",
                                JS_NewStringCopyZ(cx, clasp->name), "]");
         } else if (IsDOMIfaceAndProtoClass(clasp)) {
           const DOMIfaceAndProtoJSClass* ifaceAndProtoJSClass =
             DOMIfaceAndProtoJSClass::FromJSClass(clasp);
           str = JS_NewStringCopyZ(cx, ifaceAndProtoJSClass->mToString);
         } else {
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -133,17 +133,17 @@ UnwrapDOMObject(JSObject* obj)
 
   JS::Value val = js::GetReservedSlot(obj, DOM_OBJECT_SLOT);
   return static_cast<T*>(val.toPrivate());
 }
 
 inline const DOMClass*
 GetDOMClass(JSObject* obj)
 {
-  js::Class* clasp = js::GetObjectClass(obj);
+  const js::Class* clasp = js::GetObjectClass(obj);
   if (IsDOMClass(clasp)) {
     return &DOMJSClass::FromJSClass(clasp)->mClass;
   }
 
   if (js::IsProxyClass(clasp)) {
     js::BaseProxyHandler* handler = js::GetProxyHandler(obj);
     if (handler->family() == ProxyFamily()) {
       return &static_cast<DOMProxyHandler*>(handler)->mClass;
@@ -162,17 +162,17 @@ UnwrapDOMObjectToISupports(JSObject* aOb
   }
  
   return UnwrapDOMObject<nsISupports>(aObject);
 }
 
 inline bool
 IsDOMObject(JSObject* obj)
 {
-  js::Class* clasp = js::GetObjectClass(obj);
+  const js::Class* clasp = js::GetObjectClass(obj);
   return IsDOMClass(clasp) || IsDOMProxy(obj, clasp);
 }
 
 #define UNWRAP_OBJECT(Interface, cx, obj, value)                             \
   mozilla::dom::UnwrapObject<mozilla::dom::prototypes::id::Interface,        \
     mozilla::dom::Interface##Binding::NativeType>(cx, obj, value)
 
 // Some callers don't want to set an exception when unwrapping fails
@@ -359,19 +359,19 @@ struct NamedConstructor
  * At least one of protoClass, constructorClass or constructor should be
  * non-null. If constructorClass or constructor are non-null, the resulting
  * interface object will be defined on the given global with property name
  * |name|, which must also be non-null.
  */
 void
 CreateInterfaceObjects(JSContext* cx, JS::Handle<JSObject*> global,
                        JS::Handle<JSObject*> protoProto,
-                       JSClass* protoClass, JS::Heap<JSObject*>* protoCache,
+                       const JSClass* protoClass, JS::Heap<JSObject*>* protoCache,
                        JS::Handle<JSObject*> interfaceProto,
-                       JSClass* constructorClass, const JSNativeHolder* constructor,
+                       const JSClass* constructorClass, const JSNativeHolder* constructor,
                        unsigned ctorNargs, const NamedConstructor* namedConstructors,
                        JS::Heap<JSObject*>* constructorCache, const DOMClass* domClass,
                        const NativeProperties* regularProperties,
                        const NativeProperties* chromeOnlyProperties,
                        const char* name, bool defineOnGlobal);
 
 /*
  * Define the unforgeable attributes on an object.
@@ -478,17 +478,17 @@ SetSystemOnlyWrapperSlot(JSObject* obj, 
   MOZ_ASSERT(IsDOMClass(js::GetObjectJSClass(obj)) &&
              !(js::GetObjectJSClass(obj)->flags & JSCLASS_DOM_GLOBAL));
   js::SetReservedSlot(obj, DOM_OBJECT_SLOT_SOW, v);
 }
 
 inline bool
 GetSameCompartmentWrapperForDOMBinding(JSObject*& obj)
 {
-  js::Class* clasp = js::GetObjectClass(obj);
+  const js::Class* clasp = js::GetObjectClass(obj);
   if (dom::IsDOMClass(clasp)) {
     if (!(clasp->flags & JSCLASS_DOM_GLOBAL)) {
       JS::Value v = GetSystemOnlyWrapperSlot(obj);
       if (v.isObject()) {
         obj = &v.toObject();
       }
     }
     return true;
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -184,17 +184,17 @@ class CGDOMJSClass(CGThing):
         if self.descriptor.interface.getExtendedAttribute("NeedNewResolve"):
             newResolveHook = "(JSResolveOp)" + NEWRESOLVE_HOOK_NAME
             classFlags += " | JSCLASS_NEW_RESOLVE"
             enumerateHook = ENUMERATE_HOOK_NAME
         else:
             newResolveHook = "JS_ResolveStub"
             enumerateHook = "JS_EnumerateStub"
         return """
-static DOMJSClass Class = {
+static const DOMJSClass Class = {
   { "%s",
     %s,
     %s, /* addProperty */
     JS_DeletePropertyStub, /* delProperty */
     JS_PropertyStub,       /* getProperty */
     JS_StrictPropertyStub, /* setProperty */
     %s, /* enumerate */
     %s, /* resolve */
@@ -1006,17 +1006,17 @@ class CGAbstractClassHook(CGAbstractStat
         return self.definition_body_prologue() + self.generate_code()
 
     def generate_code(self):
         # Override me
         assert(False)
 
 class CGGetJSClassMethod(CGAbstractMethod):
     def __init__(self, descriptor):
-        CGAbstractMethod.__init__(self, descriptor, 'GetJSClass', 'JSClass*',
+        CGAbstractMethod.__init__(self, descriptor, 'GetJSClass', 'const JSClass*',
                                   [])
 
     def definition_body(self):
         return "  return Class.ToJSClass();"
 
 class CGAddPropertyHook(CGAbstractClassHook):
     """
     A hook for addProperty, used to preserve our wrapper from GC.
--- a/dom/bindings/DOMJSClass.h
+++ b/dom/bindings/DOMJSClass.h
@@ -163,47 +163,40 @@ struct DOMClass
 };
 
 // Special JSClass for reflected DOM objects.
 struct DOMJSClass
 {
   // It would be nice to just inherit from JSClass, but that precludes pure
   // compile-time initialization of the form |DOMJSClass = {...};|, since C++
   // only allows brace initialization for aggregate/POD types.
-  JSClass mBase;
-
-  DOMClass mClass;
+  const JSClass mBase;
 
-  static DOMJSClass* FromJSClass(JSClass* base) {
-    MOZ_ASSERT(base->flags & JSCLASS_IS_DOMJSCLASS);
-    return reinterpret_cast<DOMJSClass*>(base);
-  }
+  const DOMClass mClass;
+
   static const DOMJSClass* FromJSClass(const JSClass* base) {
     MOZ_ASSERT(base->flags & JSCLASS_IS_DOMJSCLASS);
     return reinterpret_cast<const DOMJSClass*>(base);
   }
 
-  static DOMJSClass* FromJSClass(js::Class* base) {
-    return FromJSClass(Jsvalify(base));
-  }
   static const DOMJSClass* FromJSClass(const js::Class* base) {
     return FromJSClass(Jsvalify(base));
   }
 
-  JSClass* ToJSClass() { return &mBase; }
+  const JSClass* ToJSClass() const { return &mBase; }
 };
 
 // Special JSClass for DOM interface and interface prototype objects.
 struct DOMIfaceAndProtoJSClass
 {
   // It would be nice to just inherit from JSClass, but that precludes pure
   // compile-time initialization of the form
   // |DOMJSInterfaceAndPrototypeClass = {...};|, since C++ only allows brace
   // initialization for aggregate/POD types.
-  JSClass mBase;
+  const JSClass mBase;
 
   // Either eInterface or eInterfacePrototype
   DOMObjectType mType;
 
   const NativePropertyHooks* mNativeHooks;
 
   // The value to return for toString() on this interface or interface prototype
   // object.
@@ -215,17 +208,17 @@ struct DOMIfaceAndProtoJSClass
   static const DOMIfaceAndProtoJSClass* FromJSClass(const JSClass* base) {
     MOZ_ASSERT(base->flags & JSCLASS_IS_DOMIFACEANDPROTOJSCLASS);
     return reinterpret_cast<const DOMIfaceAndProtoJSClass*>(base);
   }
   static const DOMIfaceAndProtoJSClass* FromJSClass(const js::Class* base) {
     return FromJSClass(Jsvalify(base));
   }
 
-  JSClass* ToJSClass() { return &mBase; }
+  const JSClass* ToJSClass() const { return &mBase; }
 };
 
 inline bool
 HasProtoAndIfaceArray(JSObject* global)
 {
   MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL);
   // This can be undefined if we GC while creating the global
   return !js::GetReservedSlot(global, DOM_PROTOTYPE_SLOT).isUndefined();
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -506,17 +506,17 @@ private:
 };
 
 class ThreadLocalJSRuntime
 {
   JSRuntime* mRuntime;
   JSContext* mContext;
   JSObject* mGlobal;
 
-  static JSClass sGlobalClass;
+  static const JSClass sGlobalClass;
   static const unsigned sRuntimeHeapSize = 768 * 1024;
 
   ThreadLocalJSRuntime()
   : mRuntime(NULL), mContext(NULL), mGlobal(NULL)
   {
       MOZ_COUNT_CTOR(ThreadLocalJSRuntime);
   }
 
@@ -577,17 +577,17 @@ class ThreadLocalJSRuntime
     }
 
     if (mRuntime) {
       JS_DestroyRuntime(mRuntime);
     }
   }
 };
 
-JSClass ThreadLocalJSRuntime::sGlobalClass = {
+const JSClass ThreadLocalJSRuntime::sGlobalClass = {
   "IndexedDBTransactionThreadGlobal",
   JSCLASS_GLOBAL_FLAGS,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
 inline
 already_AddRefed<IDBRequest>
@@ -847,17 +847,17 @@ public:
     }
 
     return obj;
   }
 };
 
 } // anonymous namespace
 
-JSClass IDBObjectStore::sDummyPropJSClass = {
+const JSClass IDBObjectStore::sDummyPropJSClass = {
   "dummy", 0,
   JS_PropertyStub,  JS_DeletePropertyStub,
   JS_PropertyStub,  JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub,
   JS_ConvertStub
 };
 
 // static
--- a/dom/indexedDB/IDBObjectStore.h
+++ b/dom/indexedDB/IDBObjectStore.h
@@ -239,17 +239,17 @@ public:
                             const Key& aKey,
                             const SerializedStructuredCloneReadInfo& aCloneInfo,
                             nsTArray<StructuredCloneFile>& aBlobs,
                             IDBCursor** _retval);
 
   void
   SetInfo(ObjectStoreInfo* aInfo);
 
-  static JSClass sDummyPropJSClass;
+  static const JSClass sDummyPropJSClass;
 
   // nsWrapperCache
   virtual JSObject*
   WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   // WebIDL
   IDBTransaction*
   GetParentObject() const
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -139,17 +139,17 @@ NPObjWrapper_Call(JSContext *cx, unsigne
 
 static bool
 NPObjWrapper_Construct(JSContext *cx, unsigned argc, JS::Value *vp);
 
 static bool
 CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject *npobj,
                      JS::Handle<jsid> id, NPVariant* getPropertyResult, JS::Value *vp);
 
-JSClass sNPObjectJSWrapperClass =
+const JSClass sNPObjectJSWrapperClass =
   {
     NPRUNTIME_JSCLASS_NAME,
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE,
     NPObjWrapper_AddProperty,
     NPObjWrapper_DelProperty,
     NPObjWrapper_GetProperty,
     NPObjWrapper_SetProperty,
     (JSEnumerateOp)NPObjWrapper_newEnumerate,
@@ -176,17 +176,17 @@ static void
 NPObjectMember_Finalize(JSFreeOp *fop, JSObject *obj);
 
 static bool
 NPObjectMember_Call(JSContext *cx, unsigned argc, JS::Value *vp);
 
 static void
 NPObjectMember_Trace(JSTracer *trc, JSObject *obj);
 
-static JSClass sNPObjectMemberClass =
+static const JSClass sNPObjectMemberClass =
   {
     "NPObject Ambiguous Member class", JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS,
     JS_PropertyStub, JS_DeletePropertyStub,
     JS_PropertyStub, JS_StrictPropertyStub, JS_EnumerateStub,
     JS_ResolveStub, NPObjectMember_Convert,
     NPObjectMember_Finalize, nullptr, NPObjectMember_Call,
     nullptr, nullptr, NPObjectMember_Trace
   };
@@ -963,17 +963,17 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS
       return nullptr;
     }
   }
 
   // No need to enter the right compartment here as we only get the
   // class and private from the JSObject, neither of which cares about
   // compartments.
 
-  JSClass *clazz = JS_GetClass(obj);
+  const JSClass *clazz = JS_GetClass(obj);
 
   if (clazz == &sNPObjectJSWrapperClass) {
     // obj is one of our own, its private data is the NPObject we're
     // looking for.
 
     NPObject *npobj = (NPObject *)::JS_GetPrivate(obj);
 
     // If the private is null, that means that the object has already been torn
--- a/dom/plugins/base/nsJSNPRuntime.h
+++ b/dom/plugins/base/nsJSNPRuntime.h
@@ -25,17 +25,17 @@ public:
   {
   }
 
   JSObject *mJSObj;
 
   const NPP mNpp;
 };
 
-extern JSClass sNPObjectJSWrapperClass;
+extern const JSClass sNPObjectJSWrapperClass;
 
 class nsJSObjWrapper : public NPObject,
                        public nsJSObjWrapperKey
 {
 public:
   static NPObject *GetNewOrUsed(NPP npp, JSContext *cx,
                                 JS::Handle<JSObject*> obj);
 
--- a/dom/workers/DOMBindingInlines.h
+++ b/dom/workers/DOMBindingInlines.h
@@ -31,17 +31,17 @@ struct WrapPrototypeTraits
 { };
 
 // XXX I kinda hate this, but we decided it wasn't worth generating this in the
 //     binding headers.
 #define SPECIALIZE_PROTO_TRAITS(_class)                                        \
   template <>                                                                  \
   struct WrapPrototypeTraits<_class>                                           \
   {                                                                            \
-    static inline JSClass*                                                     \
+    static inline const JSClass*                                               \
     GetJSClass()                                                               \
     {                                                                          \
       using namespace mozilla::dom;                                            \
       return _class##Binding_workers::GetJSClass();                            \
     }                                                                          \
                                                                                \
     static inline JSObject*                                                    \
     GetProtoObject(JSContext* aCx, JS::Handle<JSObject*> aGlobal)              \
--- a/dom/workers/Events.cpp
+++ b/dom/workers/Events.cpp
@@ -22,30 +22,30 @@
 
 using namespace mozilla;
 USING_WORKERS_NAMESPACE
 
 namespace {
 
 class Event : public PrivatizableBase
 {
-  static JSClass sClass;
-  static JSClass sMainRuntimeClass;
+  static const JSClass sClass;
+  static const JSClass sMainRuntimeClass;
 
   static const JSPropertySpec sProperties[];
   static const JSFunctionSpec sFunctions[];
   static const dom::ConstantSpec sStaticConstants[];
 
 protected:
   bool mStopPropagationCalled;
   bool mStopImmediatePropagationCalled;
 
 public:
   static bool
-  IsThisClass(JSClass* aClass)
+  IsThisClass(const JSClass* aClass)
   {
     return aClass == &sClass || aClass == &sMainRuntimeClass;
   }
 
   static JSObject*
   InitClass(JSContext* aCx, JS::Handle<JSObject*> aObj, bool aMainRuntime)
   {
     JS::Rooted<JSObject*> parentProto(aCx);
@@ -64,17 +64,17 @@ public:
         }
 
         if (!JSVAL_IS_PRIMITIVE(protoVal)) {
           parentProto = JSVAL_TO_OBJECT(protoVal);
         }
       }
     }
 
-    JSClass* clasp = parentProto ? &sMainRuntimeClass : &sClass;
+    const JSClass* clasp = parentProto ? &sMainRuntimeClass : &sClass;
 
     JS::Rooted<JSObject*> proto(aCx, JS_InitClass(aCx, aObj, parentProto, clasp, Construct, 0,
                                                   sProperties, sFunctions, nullptr, nullptr));
     if (!proto) {
       return NULL;
     }
 
     JS::Rooted<JSObject*> ctor(aCx, JS_GetConstructor(aCx, proto));
@@ -89,17 +89,17 @@ public:
 
     return proto;
   }
 
   static JSObject*
   Create(JSContext* aCx, JS::Handle<JSObject*> aParent, JS::Handle<JSString*> aType,
          bool aBubbles, bool aCancelable, bool aMainRuntime)
   {
-    JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
+    const JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
 
     JSObject* obj = JS_NewObject(aCx, clasp, NULL, aParent);
     if (obj) {
       Event* priv = new Event();
       SetJSPrivateSafeish(obj, priv);
       InitEventCommon(obj, priv, aType, aBubbles, aCancelable, true);
     }
     return obj;
@@ -329,17 +329,17 @@ private:
     }
 
     InitEventCommon(obj, event, type, bubbles, cancelable, false);
     return true;
   }
 };
 
 #define DECL_EVENT_CLASS(_varname, _name) \
-  JSClass _varname = { \
+  const JSClass _varname = { \
     _name, \
     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT), \
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, \
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize \
   };
 
 DECL_EVENT_CLASS(Event::sClass, "WorkerEvent")
 DECL_EVENT_CLASS(Event::sMainRuntimeClass, "WorkerEvent")
@@ -380,54 +380,54 @@ const dom::ConstantSpec Event::sStaticCo
   { "CAPTURING_PHASE", JS::Int32Value(CAPTURING_PHASE) },
   { "AT_TARGET", JS::Int32Value(AT_TARGET) },
   { "BUBBLING_PHASE", JS::Int32Value(BUBBLING_PHASE) },
   { nullptr, JS::UndefinedValue() }
 };
 
 class MessageEvent : public Event
 {
-  static JSClass sClass;
-  static JSClass sMainRuntimeClass;
+  static const JSClass sClass;
+  static const JSClass sMainRuntimeClass;
 
   static const JSPropertySpec sProperties[];
   static const JSFunctionSpec sFunctions[];
 
 protected:
   JSAutoStructuredCloneBuffer mBuffer;
   nsTArray<nsCOMPtr<nsISupports> > mClonedObjects;
   bool mMainRuntime;
 
 public:
   static bool
-  IsThisClass(JSClass* aClass)
+  IsThisClass(const JSClass* aClass)
   {
     return aClass == &sClass || aClass == &sMainRuntimeClass;
   }
 
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto,
             bool aMainRuntime)
   {
-    JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
+    const JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
 
     return JS_InitClass(aCx, aObj, aParentProto, clasp, Construct, 0,
                         sProperties, sFunctions, NULL, NULL);
   }
 
   static JSObject*
   Create(JSContext* aCx, JS::Handle<JSObject*> aParent, JSAutoStructuredCloneBuffer& aData,
          nsTArray<nsCOMPtr<nsISupports> >& aClonedObjects, bool aMainRuntime)
   {
     JS::Rooted<JSString*> type(aCx, JS_InternString(aCx, "message"));
     if (!type) {
       return NULL;
     }
 
-    JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
+    const JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
 
     JS::Rooted<JSObject*> obj(aCx, JS_NewObject(aCx, clasp, NULL, aParent));
     if (!obj) {
       return NULL;
     }
 
     MessageEvent* priv = new MessageEvent(aMainRuntime);
     SetJSPrivateSafeish(obj, priv);
@@ -459,17 +459,17 @@ protected:
     SLOT_COUNT,
     SLOT_FIRST = SLOT_data
   };
 
 private:
   static MessageEvent*
   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName)
   {
-    JSClass* classPtr = JS_GetClass(aObj);
+    const JSClass* classPtr = JS_GetClass(aObj);
     if (IsThisClass(classPtr)) {
       return GetJSPrivateSafeish<MessageEvent>(aObj);
     }
 
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
                          JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
                          classPtr->name);
     return NULL;
@@ -592,17 +592,17 @@ private:
 
     InitMessageEventCommon(aCx, obj, event, type, bubbles, cancelable,
                            data, origin, source, false);
     return true;
   }
 };
 
 #define DECL_MESSAGEEVENT_CLASS(_varname, _name) \
-  JSClass _varname = { \
+  const JSClass _varname = { \
     _name, \
     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT), \
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, \
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize \
   };
 
 DECL_MESSAGEEVENT_CLASS(MessageEvent::sClass, "WorkerMessageEvent")
 DECL_MESSAGEEVENT_CLASS(MessageEvent::sMainRuntimeClass, "WorkerMessageEvent")
@@ -621,49 +621,49 @@ const JSPropertySpec MessageEvent::sProp
 
 const JSFunctionSpec MessageEvent::sFunctions[] = {
   JS_FN("initMessageEvent", InitMessageEvent, 6, FUNCTION_FLAGS),
   JS_FS_END
 };
 
 class ErrorEvent : public Event
 {
-  static JSClass sClass;
-  static JSClass sMainRuntimeClass;
+  static const JSClass sClass;
+  static const JSClass sMainRuntimeClass;
 
   static const JSPropertySpec sProperties[];
   static const JSFunctionSpec sFunctions[];
 
 public:
   static bool
-  IsThisClass(JSClass* aClass)
+  IsThisClass(const JSClass* aClass)
   {
     return aClass == &sClass || aClass == &sMainRuntimeClass;
   }
 
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto,
             bool aMainRuntime)
   {
-    JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
+    const JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
 
     return JS_InitClass(aCx, aObj, aParentProto, clasp, Construct, 0,
                         sProperties, sFunctions, NULL, NULL);
   }
 
   static JSObject*
   Create(JSContext* aCx, JS::Handle<JSObject*> aParent, JS::Handle<JSString*> aMessage,
          JS::Handle<JSString*> aFilename, uint32_t aLineNumber, bool aMainRuntime)
   {
     JS::Rooted<JSString*> type(aCx, JS_InternString(aCx, "error"));
     if (!type) {
       return NULL;
     }
 
-    JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
+    const JSClass* clasp = aMainRuntime ? &sMainRuntimeClass : &sClass;
 
     JS::Rooted<JSObject*> obj(aCx, JS_NewObject(aCx, clasp, NULL, aParent));
     if (!obj) {
       return NULL;
     }
 
     ErrorEvent* priv = new ErrorEvent();
     SetJSPrivateSafeish(obj, priv);
@@ -691,17 +691,17 @@ protected:
     SLOT_COUNT,
     SLOT_FIRST = SLOT_message
   };
 
 private:
   static ErrorEvent*
   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName)
   {
-    JSClass* classPtr = JS_GetClass(aObj);
+    const JSClass* classPtr = JS_GetClass(aObj);
     if (IsThisClass(classPtr)) {
       return GetJSPrivateSafeish<ErrorEvent>(aObj);
     }
 
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
                          JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
                          classPtr->name);
     return NULL;
@@ -792,17 +792,17 @@ private:
 
     InitErrorEventCommon(obj, event, type, bubbles, cancelable, message,
                          filename, lineNumber, false);
     return true;
   }
 };
 
 #define DECL_ERROREVENT_CLASS(_varname, _name) \
-  JSClass _varname = { \
+  const JSClass _varname = { \
     _name, \
     JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT), \
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub, \
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize \
   };
 
 DECL_ERROREVENT_CLASS(ErrorEvent::sClass, "WorkerErrorEvent")
 DECL_ERROREVENT_CLASS(ErrorEvent::sMainRuntimeClass, "WorkerErrorEvent")
@@ -821,21 +821,21 @@ const JSPropertySpec ErrorEvent::sProper
 
 const JSFunctionSpec ErrorEvent::sFunctions[] = {
   JS_FN("initErrorEvent", InitErrorEvent, 6, FUNCTION_FLAGS),
   JS_FS_END
 };
 
 class ProgressEvent : public Event
 {
-  static JSClass sClass;
+  static const JSClass sClass;
   static const JSPropertySpec sProperties[];
 
 public:
-  static JSClass*
+  static const JSClass*
   Class()
   {
     return &sClass;
   }
 
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto)
   {
@@ -883,17 +883,17 @@ protected:
     SLOT_COUNT,
     SLOT_FIRST = SLOT_lengthComputable
   };
 
 private:
   static ProgressEvent*
   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName)
   {
-    JSClass* classPtr = JS_GetClass(aObj);
+    const JSClass* classPtr = JS_GetClass(aObj);
     if (classPtr == &sClass) {
       return GetJSPrivateSafeish<ProgressEvent>(aObj);
     }
 
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
                          JSMSG_INCOMPATIBLE_PROTO, sClass.name, aFunctionName,
                          classPtr->name);
     return NULL;
@@ -957,17 +957,17 @@ private:
     {
       static_assert(SLOT_FIRST <= Slot && Slot < SLOT_COUNT, "bad slot");
       JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
       return JS::CallNonGenericMethod<IsProgressEvent, GetPropertyImpl<Slot> >(aCx, args);
     }
   };
 };
 
-JSClass ProgressEvent::sClass = {
+const JSClass ProgressEvent::sClass = {
   "WorkerProgressEvent",
   JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(SLOT_COUNT),
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize
 };
 
 const JSPropertySpec ProgressEvent::sProperties[] = {
   JS_PSGS("lengthComputable", Property<SLOT_lengthComputable>::Get, GetterOnlyJSNative,
@@ -978,17 +978,17 @@ const JSPropertySpec ProgressEvent::sPro
           JSPROP_ENUMERATE),
   JS_PS_END
 };
 
 Event*
 Event::GetPrivate(JSObject* aObj)
 {
   if (aObj) {
-    JSClass* classPtr = JS_GetClass(aObj);
+    const JSClass* classPtr = JS_GetClass(aObj);
     if (IsThisClass(classPtr) ||
         MessageEvent::IsThisClass(classPtr) ||
         ErrorEvent::IsThisClass(classPtr) ||
         classPtr == ProgressEvent::Class()) {
       return GetJSPrivateSafeish<Event>(aObj);
     }
   }
   return NULL;
--- a/dom/workers/File.cpp
+++ b/dom/workers/File.cpp
@@ -26,17 +26,17 @@ using mozilla::dom::Throw;
 namespace {
 
 class Blob
 {
   // Blob should never be instantiated.
   Blob();
   ~Blob();
 
-  static JSClass sClass;
+  static const JSClass sClass;
   static const JSPropertySpec sProperties[];
   static const JSFunctionSpec sFunctions[];
 
 public:
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj)
   {
     return JS_InitClass(aCx, aObj, NULL, &sClass, Construct, 0, sProperties,
@@ -203,17 +203,17 @@ private:
       return false;
     }
 
     JS_SET_RVAL(aCx, aVp, OBJECT_TO_JSVAL(rtnObj));
     return true;
   }
 };
 
-JSClass Blob::sClass = {
+const JSClass Blob::sClass = {
   "Blob",
   JSCLASS_HAS_PRIVATE,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize
 };
 
 const JSPropertySpec Blob::sProperties[] = {
   JS_PSGS("size", GetSize, GetterOnlyJSNative, JSPROP_ENUMERATE),
@@ -227,17 +227,17 @@ const JSFunctionSpec Blob::sFunctions[] 
 };
 
 class File : public Blob
 {
   // File should never be instantiated.
   File();
   ~File();
 
-  static JSClass sClass;
+  static const JSClass sClass;
   static const JSPropertySpec sProperties[];
 
 public:
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto)
   {
     return JS_InitClass(aCx, aObj, aParentProto, &sClass, Construct, 0,
                         sProperties, NULL, NULL, NULL);
@@ -255,28 +255,28 @@ public:
     }
     return obj;
   }
 
   static nsIDOMFile*
   GetPrivate(JSObject* aObj)
   {
     if (aObj) {
-      JSClass* classPtr = JS_GetClass(aObj);
+      const JSClass* classPtr = JS_GetClass(aObj);
       if (classPtr == &sClass) {
         nsISupports* priv = static_cast<nsISupports*>(JS_GetPrivate(aObj));
         nsCOMPtr<nsIDOMFile> file = do_QueryInterface(priv);
         JS_ASSERT_IF(priv, file);
         return file;
       }
     }
     return NULL;
   }
 
-  static JSClass*
+  static const JSClass*
   Class()
   {
     return &sClass;
   }
 
 private:
   static nsIDOMFile*
   GetInstancePrivate(JSContext* aCx, JS::Handle<JSObject*> aObj, const char* aFunctionName)
@@ -421,17 +421,17 @@ private:
   static bool
   GetLastModifiedDate(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
   {
     JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
     return JS::CallNonGenericMethod<IsFile, GetLastModifiedDateImpl>(aCx, args);
   }
 };
 
-JSClass File::sClass = {
+const JSClass File::sClass = {
   "File",
   JSCLASS_HAS_PRIVATE,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize
 };
 
 const JSPropertySpec File::sProperties[] = {
   JS_PSGS("name", GetName, GetterOnlyJSNative, JSPROP_ENUMERATE),
@@ -441,17 +441,17 @@ const JSPropertySpec File::sProperties[]
   JS_PSGS("mozFullPath", GetMozFullPath, GetterOnlyJSNative, JSPROP_ENUMERATE),
   JS_PS_END
 };
 
 nsIDOMBlob*
 Blob::GetPrivate(JSObject* aObj)
 {
   if (aObj) {
-    JSClass* classPtr = JS_GetClass(aObj);
+    const JSClass* classPtr = JS_GetClass(aObj);
     if (classPtr == &sClass || classPtr == File::Class()) {
       nsISupports* priv = static_cast<nsISupports*>(JS_GetPrivate(aObj));
       nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(priv);
       JS_ASSERT_IF(priv, blob);
       return blob;
     }
   }
   return NULL;
--- a/dom/workers/Worker.cpp
+++ b/dom/workers/Worker.cpp
@@ -22,42 +22,42 @@ USING_WORKERS_NAMESPACE
 
 using namespace mozilla::dom;
 using mozilla::ErrorResult;
 
 namespace {
 
 class Worker
 {
-  static DOMJSClass sClass;
-  static DOMIfaceAndProtoJSClass sProtoClass;
+  static const DOMJSClass sClass;
+  static const DOMIfaceAndProtoJSClass sProtoClass;
   static const JSPropertySpec sProperties[];
   static const JSFunctionSpec sFunctions[];
 
 protected:
   enum {
     // The constructor function holds a WorkerPrivate* in its first reserved
     // slot.
     CONSTRUCTOR_SLOT_PARENT = 0
   };
 
 public:
-  static JSClass*
+  static const JSClass*
   Class()
   {
     return sClass.ToJSClass();
   }
 
-  static JSClass*
+  static const JSClass*
   ProtoClass()
   {
     return sProtoClass.ToJSClass();
   }
 
-  static DOMClass*
+  static const DOMClass*
   DOMClassStruct()
   {
     return &sClass.mClass;
   }
 
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto,
             bool aMainRuntime)
@@ -66,17 +66,17 @@ public:
       js::InitClassWithReserved(aCx, aObj, aParentProto, ProtoClass(),
                                 Construct, 0, sProperties, sFunctions,
                                 NULL, NULL));
     if (!proto) {
       return NULL;
     }
 
     js::SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
-                        JS::PrivateValue(DOMClassStruct()));
+                        JS::PrivateValue(const_cast<DOMClass *>(DOMClassStruct())));
 
     if (!aMainRuntime) {
       WorkerPrivate* parent = GetWorkerPrivateFromContext(aCx);
       parent->AssertIsOnWorkerThread();
 
       JSObject* constructor = JS_GetConstructor(aCx, proto);
       if (!constructor)
         return NULL;
@@ -88,17 +88,17 @@ public:
   }
 
   static WorkerPrivate*
   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName);
 
 protected:
   static bool
   ConstructInternal(JSContext* aCx, unsigned aArgc, jsval* aVp,
-                    bool aIsChromeWorker, JSClass* aClass)
+                    bool aIsChromeWorker, const JSClass* aClass)
   {
     if (!aArgc) {
       JS_ReportError(aCx, "Constructor requires at least one argument!");
       return false;
     }
 
     JS::Rooted<JSString*> scriptURL(aCx, JS_ValueToString(aCx, JS_ARGV(aCx, aVp)[0]));
     if (!scriptURL) {
@@ -341,33 +341,33 @@ private:
       return false;
     }
 
     JS_RVAL(aCx, aVp).setUndefined();
     return true;
   }
 };
 
-DOMJSClass Worker::sClass = {
+const DOMJSClass Worker::sClass = {
   {
     "Worker",
     JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(3) |
     JSCLASS_IMPLEMENTS_BARRIERS,
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize,
     NULL, NULL, NULL, NULL, Trace
   },
   {
     INTERFACE_CHAIN_1(prototypes::id::EventTarget_workers),
     false,
     &sWorkerNativePropertyHooks
   }
 };
 
-DOMIfaceAndProtoJSClass Worker::sProtoClass = {
+const DOMIfaceAndProtoJSClass Worker::sProtoClass = {
   {
     // XXXbz we use "Worker" here to match sClass so that we can
     // js::InitClassWithReserved this JSClass and then call
     // JS_NewObject with our sClass and have it find the right
     // prototype.
     "Worker",
     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(2),
     JS_PropertyStub,       /* addProperty */
@@ -401,33 +401,33 @@ const JSPropertySpec Worker::sProperties
 const JSFunctionSpec Worker::sFunctions[] = {
   JS_FN("terminate", Terminate, 0, FUNCTION_FLAGS),
   JS_FN("postMessage", PostMessage, 1, FUNCTION_FLAGS),
   JS_FS_END
 };
 
 class ChromeWorker : public Worker
 {
-  static DOMJSClass sClass;
-  static DOMIfaceAndProtoJSClass sProtoClass;
+  static const DOMJSClass sClass;
+  static const DOMIfaceAndProtoJSClass sProtoClass;
 
 public:
-  static JSClass*
+  static const JSClass*
   Class()
   {
     return sClass.ToJSClass();
   }
 
-  static JSClass*
+  static const JSClass*
   ProtoClass()
   {
     return sProtoClass.ToJSClass();
   }
 
-  static DOMClass*
+  static const DOMClass*
   DOMClassStruct()
   {
     return &sClass.mClass;
   }
 
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto,
             bool aMainRuntime)
@@ -435,17 +435,17 @@ public:
     JS::Rooted<JSObject*> proto(aCx,
       js::InitClassWithReserved(aCx, aObj, aParentProto, ProtoClass(),
                                 Construct, 0, NULL, NULL, NULL, NULL));
     if (!proto) {
       return NULL;
     }
 
     js::SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
-                        JS::PrivateValue(DOMClassStruct()));
+                        JS::PrivateValue(const_cast<DOMClass *>(DOMClassStruct())));
 
     if (!aMainRuntime) {
       WorkerPrivate* parent = GetWorkerPrivateFromContext(aCx);
       parent->AssertIsOnWorkerThread();
 
       JSObject* constructor = JS_GetConstructor(aCx, proto);
       if (!constructor)
         return NULL;
@@ -462,17 +462,17 @@ private:
   // make one.
   ChromeWorker();
   ~ChromeWorker();
 
   static WorkerPrivate*
   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName)
   {
     if (aObj) {
-      JSClass* classPtr = JS_GetClass(aObj);
+      const JSClass* classPtr = JS_GetClass(aObj);
       if (classPtr == Class()) {
         return UnwrapDOMObject<WorkerPrivate>(aObj);
       }
     }
 
     return Worker::GetInstancePrivate(aCx, aObj, aFunctionName);
   }
 
@@ -498,32 +498,32 @@ private:
     JS_ASSERT(JS_GetClass(aObj) == Class());
     WorkerPrivate* worker = UnwrapDOMObject<WorkerPrivate>(aObj);
     if (worker) {
       worker->_trace(aTrc);
     }
   }
 };
 
-DOMJSClass ChromeWorker::sClass = {
+const DOMJSClass ChromeWorker::sClass = {
   { "ChromeWorker",
     JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(3) |
     JSCLASS_IMPLEMENTS_BARRIERS,
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Finalize,
     NULL, NULL, NULL, NULL, Trace,
   },
   {
     INTERFACE_CHAIN_1(prototypes::id::EventTarget_workers),
     false,
     &sWorkerNativePropertyHooks
   }
 };
 
-DOMIfaceAndProtoJSClass ChromeWorker::sProtoClass = {
+const DOMIfaceAndProtoJSClass ChromeWorker::sProtoClass = {
   {
     // XXXbz we use "ChromeWorker" here to match sClass so that we can
     // js::InitClassWithReserved this JSClass and then call
     // JS_NewObject with our sClass and have it find the right
     // prototype.
     "ChromeWorker",
     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(2),
     JS_PropertyStub,       /* addProperty */
@@ -547,17 +547,17 @@ DOMIfaceAndProtoJSClass ChromeWorker::sP
   prototypes::id::_ID_Count,
   0
 };
 
 WorkerPrivate*
 Worker::GetInstancePrivate(JSContext* aCx, JSObject* aObj,
                            const char* aFunctionName)
 {
-  JSClass* classPtr = JS_GetClass(aObj);
+  const JSClass* classPtr = JS_GetClass(aObj);
   if (ClassIsWorker(classPtr)) {
     return UnwrapDOMObject<WorkerPrivate>(aObj);
   }
 
   JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL, JSMSG_INCOMPATIBLE_PROTO,
                        Class()->name, aFunctionName, classPtr->name);
   return NULL;
 }
@@ -601,17 +601,17 @@ InitClass(JSContext* aCx, JSObject* aGlo
           bool aMainRuntime)
 {
   return !!ChromeWorker::InitClass(aCx, aGlobal, aProto, aMainRuntime);
 }
 
 } // namespace chromeworker
 
 bool
-ClassIsWorker(JSClass* aClass)
+ClassIsWorker(const JSClass* aClass)
 {
   return Worker::Class() == aClass || ChromeWorker::Class() == aClass;
 }
 
 bool
 GetterOnlyJSNative(JSContext* aCx, unsigned aArgc, JS::Value* aVp)
 {
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, nullptr, JSMSG_GETTER_ONLY);
--- a/dom/workers/Worker.h
+++ b/dom/workers/Worker.h
@@ -22,13 +22,13 @@ namespace chromeworker {
 
 bool
 InitClass(JSContext* aCx, JSObject* aGlobal, JSObject* aProto,
           bool aMainRuntime);
 
 } // namespace chromeworker
 
 bool
-ClassIsWorker(JSClass* aClass);
+ClassIsWorker(const JSClass* aClass);
 
 END_WORKERS_NAMESPACE
 
 #endif /* mozilla_dom_workers_worker_h__ */
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -56,17 +56,17 @@ using namespace mozilla;
 using namespace mozilla::dom;
 USING_WORKERS_NAMESPACE
 
 namespace {
 
 class WorkerGlobalScope : public workers::EventTarget,
                           public nsIGlobalObject
 {
-  static JSClass sClass;
+  static const JSClass sClass;
   static const JSPropertySpec sProperties[];
   static const JSFunctionSpec sFunctions[];
 
   enum
   {
     SLOT_wrappedScope = 0,
     SLOT_wrappedFunction
   };
@@ -91,17 +91,17 @@ class WorkerGlobalScope : public workers
   };
 
   static const char* const sEventStrings[STRING_COUNT];
 
 protected:
   WorkerPrivate* mWorker;
 
 public:
-  static JSClass*
+  static const JSClass*
   Class()
   {
     return &sClass;
   }
 
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto)
   {
@@ -648,17 +648,17 @@ private:
 NS_IMPL_ADDREF_INHERITED(WorkerGlobalScope, workers::EventTarget)
 NS_IMPL_RELEASE_INHERITED(WorkerGlobalScope, workers::EventTarget)
 
 NS_INTERFACE_MAP_BEGIN(WorkerGlobalScope)
   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, DOMBindingBase)
 NS_INTERFACE_MAP_END
 
-JSClass WorkerGlobalScope::sClass = {
+const JSClass WorkerGlobalScope::sClass = {
   "WorkerGlobalScope",
   0,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
 const JSPropertySpec WorkerGlobalScope::sProperties[] = {
   JS_PSGS("location", GetLocation, GetterOnlyJSNative, JSPROP_ENUMERATE),
@@ -686,58 +686,58 @@ const JSFunctionSpec WorkerGlobalScope::
 
 const char* const WorkerGlobalScope::sEventStrings[STRING_COUNT] = {
   "onerror",
   "onclose"
 };
 
 class DedicatedWorkerGlobalScope : public WorkerGlobalScope
 {
-  static DOMJSClass sClass;
-  static DOMIfaceAndProtoJSClass sProtoClass;
+  static const DOMJSClass sClass;
+  static const DOMIfaceAndProtoJSClass sProtoClass;
   static const JSPropertySpec sProperties[];
   static const JSFunctionSpec sFunctions[];
 
   enum
   {
     STRING_onmessage = 0,
 
     STRING_COUNT
   };
 
   static const char* const sEventStrings[STRING_COUNT];
 
 public:
-  static JSClass*
+  static const JSClass*
   Class()
   {
     return sClass.ToJSClass();
   }
 
-  static JSClass*
+  static const JSClass*
   ProtoClass()
   {
     return sProtoClass.ToJSClass();
   }
 
-  static DOMClass*
+  static const DOMClass*
   DOMClassStruct()
   {
     return &sClass.mClass;
   }
 
   static JSObject*
   InitClass(JSContext* aCx, JSObject* aObj, JSObject* aParentProto)
   {
     JSObject* proto =
       JS_InitClass(aCx, aObj, aParentProto, ProtoClass(), Construct, 0,
                    sProperties, sFunctions, NULL, NULL);
     if (proto) {
       js::SetReservedSlot(proto, DOM_PROTO_INSTANCE_CLASS_SLOT,
-                          JS::PrivateValue(DOMClassStruct()));
+                          JS::PrivateValue(const_cast<DOMClass *>(DOMClassStruct())));
     }
     return proto;
   }
 
   static bool
   InitPrivate(JSContext* aCx, JSObject* aObj, WorkerPrivate* aWorkerPrivate)
   {
     JS_ASSERT(JS_GetClass(aObj) == Class());
@@ -840,17 +840,17 @@ private:
   {
     JS::CallArgs args = JS::CallArgsFromVp(aArgc, aVp);
     return JS::CallNonGenericMethod<IsDedicatedWorkerGlobalScope, SetOnMessageImpl>(aCx, args);
   }
 
   static DedicatedWorkerGlobalScope*
   GetInstancePrivate(JSContext* aCx, JSObject* aObj, const char* aFunctionName)
   {
-    JSClass* classPtr = JS_GetClass(aObj);
+    const JSClass* classPtr = JS_GetClass(aObj);
     if (classPtr == Class()) {
       return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
     }
 
     JS_ReportErrorNumber(aCx, js_GetErrorMessage, NULL,
                          JSMSG_INCOMPATIBLE_PROTO, Class()->name, aFunctionName,
                          classPtr->name);
     return NULL;
@@ -926,17 +926,17 @@ private:
       return false;
     }
 
     JS_RVAL(aCx, aVp).setUndefined();
     return true;
   }
 };
 
-DOMJSClass DedicatedWorkerGlobalScope::sClass = {
+const DOMJSClass DedicatedWorkerGlobalScope::sClass = {
   {
     // We don't have to worry about Xray expando slots here because we'll never
     // have an Xray wrapper to a worker global scope.
     "DedicatedWorkerGlobalScope",
     JSCLASS_DOM_GLOBAL | JSCLASS_IS_DOMJSCLASS | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(DOM_GLOBAL_SLOTS) | JSCLASS_NEW_RESOLVE,
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, reinterpret_cast<JSResolveOp>(Resolve), JS_ConvertStub,
@@ -944,17 +944,17 @@ DOMJSClass DedicatedWorkerGlobalScope::s
   },
   {
     INTERFACE_CHAIN_1(prototypes::id::EventTarget_workers),
     false,
     &sWorkerNativePropertyHooks
   }
 };
 
-DOMIfaceAndProtoJSClass DedicatedWorkerGlobalScope::sProtoClass = {
+const DOMIfaceAndProtoJSClass DedicatedWorkerGlobalScope::sProtoClass = {
   {
     // XXXbz we use "DedicatedWorkerGlobalScope" here to match sClass
     // so that we can JS_InitClass this JSClass and then
     // call JS_NewObject with our sClass and have it find the right
     // prototype.
     "DedicatedWorkerGlobalScope",
     JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(2),
     JS_PropertyStub,       /* addProperty */
@@ -993,17 +993,17 @@ const JSFunctionSpec DedicatedWorkerGlob
 const char* const DedicatedWorkerGlobalScope::sEventStrings[STRING_COUNT] = {
   "onmessage",
 };
 
 WorkerGlobalScope*
 WorkerGlobalScope::GetInstancePrivate(JSContext* aCx, JSObject* aObj,
                                       const char* aFunctionName)
 {
-  JSClass* classPtr = JS_GetClass(aObj);
+  const JSClass* classPtr = JS_GetClass(aObj);
 
   // We can only make DedicatedWorkerGlobalScope, not WorkerGlobalScope, so this
   // should never happen.
   JS_ASSERT(classPtr != Class());
 
   if (classPtr == DedicatedWorkerGlobalScope::Class()) {
     return UnwrapDOMObject<DedicatedWorkerGlobalScope>(aObj);
   }
@@ -1116,15 +1116,15 @@ CreateDedicatedWorkerGlobalScope(JSConte
   }
 
   JS_FireOnNewGlobalObject(aCx, global);
 
   return global;
 }
 
 bool
-ClassIsWorkerGlobalScope(JSClass* aClass)
+ClassIsWorkerGlobalScope(const JSClass* aClass)
 {
   return WorkerGlobalScope::Class() == aClass ||
          DedicatedWorkerGlobalScope::Class() == aClass;
 }
 
 END_WORKERS_NAMESPACE
--- a/dom/workers/WorkerScope.h
+++ b/dom/workers/WorkerScope.h
@@ -9,13 +9,13 @@
 #include "Workers.h"
 
 BEGIN_WORKERS_NAMESPACE
 
 JSObject*
 CreateDedicatedWorkerGlobalScope(JSContext* aCx);
 
 bool
-ClassIsWorkerGlobalScope(JSClass* aClass);
+ClassIsWorkerGlobalScope(const JSClass* aClass);
 
 END_WORKERS_NAMESPACE
 
 #endif /* mozilla_dom_workers_workerscope_h__ */
--- a/js/jsd/jsd_high.cpp
+++ b/js/jsd/jsd_high.cpp
@@ -42,22 +42,22 @@ void JSD_ASSERT_VALID_CONTEXT(JSDContext
 
 /***************************************************************************/
 /* xpconnect related utility functions implemented in jsd_xpc.cpp */
 
 extern void
 global_finalize(JSFreeOp* fop, JSObject* obj);
 
 extern JSObject*
-CreateJSDGlobal(JSContext *cx, JSClass *clasp);
+CreateJSDGlobal(JSContext *cx, const JSClass *clasp);
 
 /***************************************************************************/
 
 
-static JSClass global_class = {
+static const JSClass global_class = {
     "JSDGlobal", JSCLASS_GLOBAL_FLAGS |
     JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS,
     JS_PropertyStub,  JS_DeletePropertyStub,  JS_PropertyStub,  JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   global_finalize
 };
 
 static bool
 _validateUserCallbacks(JSD_UserCallbacks* callbacks)
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -3338,17 +3338,17 @@ global_finalize(JSFreeOp *aFop, JSObject
     nsIScriptObjectPrincipal *sop =
         static_cast<nsIScriptObjectPrincipal *>(js::GetObjectPrivate(aObj));
     MOZ_ASSERT(sop);
     static_cast<SandboxPrivate *>(sop)->ForgetGlobalObject();
     NS_IF_RELEASE(sop);
 }
 
 JSObject *
-CreateJSDGlobal(JSContext *aCx, JSClass *aClasp)
+CreateJSDGlobal(JSContext *aCx, const JSClass *aClasp)
 {
     nsresult rv;
     nsCOMPtr<nsIPrincipal> nullPrin = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
     NS_ENSURE_SUCCESS(rv, nullptr);
 
     JSPrincipals *jsPrin = nsJSPrincipals::get(nullPrin);
     JS::RootedObject global(aCx, JS_NewGlobalObject(aCx, aClasp, jsPrin, JS::DontFireOnNewGlobalHook));
     NS_ENSURE_TRUE(global, nullptr);
--- a/js/public/CallNonGenericMethod.h
+++ b/js/public/CallNonGenericMethod.h
@@ -36,17 +36,17 @@ CallMethodIfWrapped(JSContext *cx, IsAcc
 // work properly without entering that object's compartment.  This method
 // implements a solution to this problem.
 //
 // To implement a method that accepts |this| values from multiple compartments,
 // define two functions.  The first function matches the IsAcceptableThis type
 // and indicates whether the provided value is an acceptable |this| for the
 // method; it must be a pure function only of its argument.
 //
-//   static JSClass AnswerClass = { ... };
+//   static const JSClass AnswerClass = { ... };
 //
 //   static bool
 //   IsAnswerObject(const Value &v)
 //   {
 //       if (!v.isObject())
 //           return false;
 //       return JS_GetClass(&v.toObject()) == &AnswerClass;
 //   }
--- a/js/public/Class.h
+++ b/js/public/Class.h
@@ -30,17 +30,17 @@ class Class;
 class FreeOp;
 class PropertyId;
 class PropertyName;
 class Shape;
 class SpecialId;
 
 // This is equal to JSFunction::class_.  Use it in places where you don't want
 // to #include jsfun.h.
-extern JS_FRIEND_DATA(js::Class* const) FunctionClassPtr;
+extern JS_FRIEND_DATA(const js::Class* const) FunctionClassPtr;
 
 static JS_ALWAYS_INLINE jsid
 SPECIALID_TO_JSID(const SpecialId &sid);
 
 /*
  * We partition the ways to refer to a property into three: by an index
  * (uint32_t); by a string whose characters do not represent an index
  * (PropertyName, see vm/String.h); and by various special values.
@@ -624,32 +624,22 @@ JS_STATIC_ASSERT(offsetof(JSClass, conve
 JS_STATIC_ASSERT(offsetof(JSClass, finalize) == offsetof(Class, finalize));
 JS_STATIC_ASSERT(offsetof(JSClass, checkAccess) == offsetof(Class, checkAccess));
 JS_STATIC_ASSERT(offsetof(JSClass, call) == offsetof(Class, call));
 JS_STATIC_ASSERT(offsetof(JSClass, construct) == offsetof(Class, construct));
 JS_STATIC_ASSERT(offsetof(JSClass, hasInstance) == offsetof(Class, hasInstance));
 JS_STATIC_ASSERT(offsetof(JSClass, trace) == offsetof(Class, trace));
 JS_STATIC_ASSERT(sizeof(JSClass) == sizeof(Class));
 
-static JS_ALWAYS_INLINE JSClass *
-Jsvalify(Class *c)
-{
-    return (JSClass *)c;
-}
 static JS_ALWAYS_INLINE const JSClass *
 Jsvalify(const Class *c)
 {
     return (const JSClass *)c;
 }
 
-static JS_ALWAYS_INLINE Class *
-Valueify(JSClass *c)
-{
-    return (Class *)c;
-}
 static JS_ALWAYS_INLINE const Class *
 Valueify(const JSClass *c)
 {
     return (const Class *)c;
 }
 
 /*
  * Enumeration describing possible values of the [[Class]] internal property
--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -542,17 +542,17 @@ static const size_t INITIAL_STRING_BUFFE
 
 /******************** Collator ********************/
 
 static void collator_finalize(FreeOp *fop, JSObject *obj);
 
 static const uint32_t UCOLLATOR_SLOT = 0;
 static const uint32_t COLLATOR_SLOTS_COUNT = 1;
 
-static Class CollatorClass = {
+static const Class CollatorClass = {
     js_Object_str,
     JSCLASS_HAS_RESERVED_SLOTS(COLLATOR_SLOTS_COUNT),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
@@ -1025,17 +1025,17 @@ js::intl_CompareStrings(JSContext *cx, u
 
 /******************** NumberFormat ********************/
 
 static void numberFormat_finalize(FreeOp *fop, JSObject *obj);
 
 static const uint32_t UNUMBER_FORMAT_SLOT = 0;
 static const uint32_t NUMBER_FORMAT_SLOTS_COUNT = 1;
 
-static Class NumberFormatClass = {
+static const Class NumberFormatClass = {
     js_Object_str,
     JSCLASS_HAS_RESERVED_SLOTS(NUMBER_FORMAT_SLOTS_COUNT),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
@@ -1481,17 +1481,17 @@ js::intl_FormatNumber(JSContext *cx, uns
 
 /******************** DateTimeFormat ********************/
 
 static void dateTimeFormat_finalize(FreeOp *fop, JSObject *obj);
 
 static const uint32_t UDATE_FORMAT_SLOT = 0;
 static const uint32_t DATE_TIME_FORMAT_SLOTS_COUNT = 1;
 
-static Class DateTimeFormatClass = {
+static const Class DateTimeFormatClass = {
     js_Object_str,
     JSCLASS_HAS_RESERVED_SLOTS(DATE_TIME_FORMAT_SLOTS_COUNT),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
@@ -1963,17 +1963,17 @@ js::intl_FormatDateTime(JSContext *cx, u
         return false;
     args.rval().set(result);
     return true;
 }
 
 
 /******************** Intl ********************/
 
-Class js::IntlClass = {
+const Class js::IntlClass = {
     js_Object_str,
     JSCLASS_HAS_CACHED_PROTO(JSProto_Intl),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -850,17 +850,17 @@ HashableValue::mark(JSTracer *trc) const
 
 /*** MapIterator *********************************************************************************/
 
 namespace {
 
 class MapIteratorObject : public JSObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 
     enum { TargetSlot, KindSlot, RangeSlot, SlotCount };
     static const JSFunctionSpec methods[];
     static MapIteratorObject *create(JSContext *cx, HandleObject mapobj, ValueMap *data,
                                      MapObject::IteratorKind kind);
     static void finalize(FreeOp *fop, JSObject *obj);
 
   private:
@@ -868,17 +868,17 @@ class MapIteratorObject : public JSObjec
     inline ValueMap::Range *range();
     inline MapObject::IteratorKind kind() const;
     static bool next_impl(JSContext *cx, CallArgs args);
     static bool next(JSContext *cx, unsigned argc, Value *vp);
 };
 
 } /* anonymous namespace */
 
-Class MapIteratorObject::class_ = {
+const Class MapIteratorObject::class_ = {
     "Map Iterator",
     JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(MapIteratorObject::SlotCount),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
@@ -1001,17 +1001,17 @@ MapIteratorObject::next(JSContext *cx, u
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod(cx, is, next_impl, args);
 }
 
 
 /*** Map *****************************************************************************************/
 
-Class MapObject::class_ = {
+const Class MapObject::class_ = {
     "Map",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Map),
     JS_PropertyStub,         // addProperty
     JS_DeletePropertyStub,   // delProperty
     JS_PropertyStub,         // getProperty
     JS_StrictPropertyStub,   // setProperty
     JS_EnumerateStub,
@@ -1038,17 +1038,17 @@ const JSFunctionSpec MapObject::methods[
     JS_FN("keys", keys, 0, 0),
     JS_FN("values", values, 0, 0),
     JS_FN("clear", clear, 0, 0),
     {"forEach", {NULL, NULL}, 2, 0, "MapForEach"},
     JS_FS_END
 };
 
 static JSObject *
-InitClass(JSContext *cx, Handle<GlobalObject*> global, Class *clasp, JSProtoKey key, Native construct,
+InitClass(JSContext *cx, Handle<GlobalObject*> global, const Class *clasp, JSProtoKey key, Native construct,
           const JSPropertySpec *properties, const JSFunctionSpec *methods)
 {
     Rooted<JSObject*> proto(cx, global->createBlankPrototype(cx, clasp));
     if (!proto)
         return NULL;
     proto->setPrivate(NULL);
 
     Rooted<JSFunction*> ctor(cx, global->createConstructor(cx, construct, ClassName(key, cx), 1));
@@ -1417,17 +1417,17 @@ js_InitMapClass(JSContext *cx, HandleObj
 
 /*** SetIterator *********************************************************************************/
 
 namespace {
 
 class SetIteratorObject : public JSObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 
     enum { TargetSlot, KindSlot, RangeSlot, SlotCount };
     static const JSFunctionSpec methods[];
     static SetIteratorObject *create(JSContext *cx, HandleObject setobj, ValueSet *data,
                                      SetObject::IteratorKind kind);
     static void finalize(FreeOp *fop, JSObject *obj);
 
   private:
@@ -1435,17 +1435,17 @@ class SetIteratorObject : public JSObjec
     inline ValueSet::Range *range();
     inline SetObject::IteratorKind kind() const;
     static bool next_impl(JSContext *cx, CallArgs args);
     static bool next(JSContext *cx, unsigned argc, Value *vp);
 };
 
 } /* anonymous namespace */
 
-Class SetIteratorObject::class_ = {
+const Class SetIteratorObject::class_ = {
     "Set Iterator",
     JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(SetIteratorObject::SlotCount),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
@@ -1564,17 +1564,17 @@ SetIteratorObject::next(JSContext *cx, u
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod(cx, is, next_impl, args);
 }
 
 
 /*** Set *****************************************************************************************/
 
-Class SetObject::class_ = {
+const Class SetObject::class_ = {
     "Set",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Set),
     JS_PropertyStub,         // addProperty
     JS_DeletePropertyStub,   // delProperty
     JS_PropertyStub,         // getProperty
     JS_StrictPropertyStub,   // setProperty
     JS_EnumerateStub,
--- a/js/src/builtin/MapObject.h
+++ b/js/src/builtin/MapObject.h
@@ -83,17 +83,17 @@ typedef OrderedHashSet<HashableValue,
                        HashableValue::Hasher,
                        RuntimeAllocPolicy> ValueSet;
 
 class MapObject : public JSObject {
   public:
     enum IteratorKind { Keys, Values, Entries };
 
     static JSObject *initClass(JSContext *cx, JSObject *obj);
-    static Class class_;
+    static const Class class_;
   private:
     static const JSPropertySpec properties[];
     static const JSFunctionSpec methods[];
     ValueMap *getData() { return static_cast<ValueMap *>(getPrivate()); }
     static ValueMap & extract(CallReceiver call);
     static void mark(JSTracer *trc, JSObject *obj);
     static void finalize(FreeOp *fop, JSObject *obj);
     static bool construct(JSContext *cx, unsigned argc, Value *vp);
@@ -121,17 +121,17 @@ class MapObject : public JSObject {
     static bool clear_impl(JSContext *cx, CallArgs args);
     static bool clear(JSContext *cx, unsigned argc, Value *vp);
 };
 
 class SetObject : public JSObject {
   public:
     enum IteratorKind { Values, Entries };
     static JSObject *initClass(JSContext *cx, JSObject *obj);
-    static Class class_;
+    static const Class class_;
   private:
     static const JSPropertySpec properties[];
     static const JSFunctionSpec methods[];
     ValueSet *getData() { return static_cast<ValueSet *>(getPrivate()); }
     static ValueSet & extract(CallReceiver call);
     static void mark(JSTracer *trc, JSObject *obj);
     static void finalize(FreeOp *fop, JSObject *obj);
     static bool construct(JSContext *cx, unsigned argc, Value *vp);
--- a/js/src/builtin/Module.cpp
+++ b/js/src/builtin/Module.cpp
@@ -9,17 +9,17 @@
 #include "jsobjinlines.h"
 
 using namespace js;
 
 namespace js {
 typedef Rooted<Module*> RootedModule;
 }
 
-Class Module::class_ = {
+const Class Module::class_ = {
     "Module",
     JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_IS_ANONYMOUS,
     JS_PropertyStub,        /* addProperty */
     JS_DeletePropertyStub,  /* delProperty */
     JS_PropertyStub,        /* getProperty */
     JS_StrictPropertyStub,  /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/builtin/Module.h
+++ b/js/src/builtin/Module.h
@@ -18,17 +18,17 @@ class Module : public JSObject {
     JSAtom *atom() {
         return &getReservedSlot(ATOM_SLOT).toString()->asAtom();
     };
 
     JSScript *script() {
         return (JSScript *) getReservedSlot(SCRIPT_SLOT).toPrivate();
     }
 
-    static Class class_;
+    static const Class class_;
 
   private:
     inline void setAtom(JSAtom *atom);
     inline void setScript(JSScript *script);
 
     static const uint32_t ATOM_SLOT = 0;
     static const uint32_t SCRIPT_SLOT = 1;
 };
--- a/js/src/builtin/ParallelArray.cpp
+++ b/js/src/builtin/ParallelArray.cpp
@@ -39,29 +39,29 @@ const JSFunctionSpec ParallelArrayObject
     // TI to track the dimensionality of the receiver and (2) using a
     // hint to aggressively inline calls to get().
     // { "get",      JSOP_NULLWRAPPER, 1, 0, "ParallelArrayGet" },
 
     { "toString", JSOP_NULLWRAPPER, 0, 0, "ParallelArrayToString" },
     JS_FS_END
 };
 
-Class ParallelArrayObject::protoClass = {
+const Class ParallelArrayObject::protoClass = {
     "ParallelArray",
     JSCLASS_HAS_CACHED_PROTO(JSProto_ParallelArray),
     JS_PropertyStub,         // addProperty
     JS_DeletePropertyStub,   // delProperty
     JS_PropertyStub,         // getProperty
     JS_StrictPropertyStub,   // setProperty
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub
 };
 
-Class ParallelArrayObject::class_ = {
+const Class ParallelArrayObject::class_ = {
     "ParallelArray",
     JSCLASS_HAS_CACHED_PROTO(JSProto_ParallelArray),
     JS_PropertyStub,         // addProperty
     JS_DeletePropertyStub,   // delProperty
     JS_PropertyStub,         // getProperty
     JS_StrictPropertyStub,   // setProperty
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/builtin/ParallelArray.h
+++ b/js/src/builtin/ParallelArray.h
@@ -10,26 +10,26 @@
 #include "jsobj.h"
 
 #include "jit/Ion.h"
 
 namespace js {
 
 class ParallelArrayObject : public JSObject
 {
-    static Class protoClass;
+    static const Class protoClass;
     static const JSFunctionSpec methods[];
     static const uint32_t NumFixedSlots = 4;
     static const uint32_t NumCtors = 4;
     static FixedHeapPtr<PropertyName> ctorNames[NumCtors];
 
     static bool initProps(JSContext *cx, HandleObject obj);
 
   public:
-    static Class class_;
+    static const Class class_;
 
     static bool construct(JSContext *cx, unsigned argc, Value *vp);
     static bool constructHelper(JSContext *cx, MutableHandleFunction ctor, CallArgs &args);
 
     // Creates a new ParallelArray instance with the correct number of slots
     // and so forth.
     //
     // NOTE: This object will NOT have the correct type object! It is
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -785,17 +785,17 @@ OOMAfterAllocations(JSContext *cx, unsig
 static unsigned finalizeCount = 0;
 
 static void
 finalize_counter_finalize(JSFreeOp *fop, JSObject *obj)
 {
     ++finalizeCount;
 }
 
-static JSClass FinalizeCounterClass = {
+static const JSClass FinalizeCounterClass = {
     "FinalizeCounter", JSCLASS_IS_ANONYMOUS,
     JS_PropertyStub,       /* addProperty */
     JS_DeletePropertyStub, /* delProperty */
     JS_PropertyStub,       /* getProperty */
     JS_StrictPropertyStub, /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub,
--- a/js/src/builtin/TypeRepresentation.cpp
+++ b/js/src/builtin/TypeRepresentation.cpp
@@ -20,17 +20,17 @@
 #include "jsobjinlines.h"
 
 using namespace js;
 using namespace mozilla;
 
 ///////////////////////////////////////////////////////////////////////////
 // Class def'n for the owner object
 
-Class TypeRepresentation::class_ = {
+const Class TypeRepresentation::class_ = {
     "TypeRepresentation",
     JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_PRIVATE,
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
--- a/js/src/builtin/TypeRepresentation.h
+++ b/js/src/builtin/TypeRepresentation.h
@@ -100,17 +100,17 @@ class TypeRepresentation {
 
     size_t size_;
     size_t alignment_;
     Kind kind_;
 
     JSObject *addToTableOrFree(JSContext *cx, TypeRepresentationSet::AddPtr &p);
 
   private:
-    static Class class_;
+    static const Class class_;
     static void obj_trace(JSTracer *trace, JSObject *object);
     static void obj_finalize(js::FreeOp *fop, JSObject *object);
 
     js::HeapPtrObject ownerObject_;
     void traceFields(JSTracer *tracer);
 
   public:
     size_t size() const { return size_; }
--- a/js/src/builtin/TypedObject.cpp
+++ b/js/src/builtin/TypedObject.cpp
@@ -238,29 +238,29 @@ IsBinaryArray(JSContext *cx, HandleObjec
 }
 
 static inline bool
 IsBinaryStruct(JSContext *cx, HandleObject obj)
 {
     return IsBlockOfKind(cx, obj, TypeRepresentation::Struct);
 }
 
-Class js::DataClass = {
+const Class js::DataClass = {
     "Data",
     JSCLASS_HAS_CACHED_PROTO(JSProto_Data),
     JS_PropertyStub,
     JS_DeletePropertyStub,
     JS_PropertyStub,
     JS_StrictPropertyStub,
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub
 };
 
-Class js::TypeClass = {
+const Class js::TypeClass = {
     "Type",
     JSCLASS_HAS_CACHED_PROTO(JSProto_Type),
     JS_PropertyStub,
     JS_DeletePropertyStub,
     JS_PropertyStub,
     JS_StrictPropertyStub,
     JS_EnumerateStub,
     JS_ResolveStub,
@@ -314,17 +314,17 @@ TypeEquivalent(JSContext *cx, unsigned i
     NULL,                                                                     \
     NULL,                                                                     \
     NumericType<constant_, type_>::call,                                      \
     NULL,                                                                     \
     NULL,                                                                     \
     NULL                                                                      \
 },
 
-Class js::NumericTypeClasses[ScalarTypeRepresentation::TYPE_MAX] = {
+const Class js::NumericTypeClasses[ScalarTypeRepresentation::TYPE_MAX] = {
     JS_FOR_EACH_SCALAR_TYPE_REPR(BINARYDATA_NUMERIC_CLASSES)
 };
 
 template <typename Domain, typename Input>
 bool
 InRange(Input x)
 {
     return std::numeric_limits<Domain>::min() <= x &&
@@ -360,17 +360,17 @@ bool
 InRange<double, double>(double x)
 {
     return -std::numeric_limits<double>::max() <= x &&
            x <= std::numeric_limits<double>::max();
 }
 
 #define BINARYDATA_TYPE_TO_CLASS(constant_, type_, name_)                     \
     template <>                                                               \
-    Class *                                                                   \
+    const Class *                                                             \
     NumericType<constant_, type_>::typeToClass()                              \
     {                                                                         \
         return &NumericTypeClasses[constant_];                                \
     }
 
 /**
  * This namespace declaration is required because of a weird 'specialization in
  * different namespace' error that happens in gcc, only on type specialized
@@ -549,17 +549,17 @@ SetupAndGetPrototypeObjectForComplexType
     JS_ASSERT(complexTypePrototypePrototypeVal.isObject()); // immutable binding
     RootedObject proto(cx, &complexTypePrototypePrototypeVal.toObject());
     if (!JS_SetPrototype(cx, prototypeObj, proto))
         return NULL;
 
     return prototypeObj;
 }
 
-Class ArrayType::class_ = {
+const Class ArrayType::class_ = {
     "ArrayType",
     JSCLASS_HAS_RESERVED_SLOTS(ARRAY_TYPE_RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_ArrayType),
     JS_PropertyStub,
     JS_DeletePropertyStub,
     JS_PropertyStub,
     JS_StrictPropertyStub,
     JS_EnumerateStub,
@@ -1023,17 +1023,17 @@ ArrayType::construct(JSContext *cx, unsi
         return false;
     args.rval().setObject(*obj);
     return true;
 }
 
 /*********************************
  * Structs
  *********************************/
-Class StructType::class_ = {
+const Class StructType::class_ = {
     "StructType",
     JSCLASS_HAS_RESERVED_SLOTS(STRUCT_TYPE_RESERVED_SLOTS) |
     JSCLASS_HAS_PRIVATE | // used to store FieldList
     JSCLASS_HAS_CACHED_PROTO(JSProto_StructType),
     JS_PropertyStub,
     JS_DeletePropertyStub,
     JS_PropertyStub,
     JS_StrictPropertyStub,
@@ -1567,17 +1567,17 @@ static bool
 DefineNumericClass(JSContext *cx,
                    HandleObject global,
                    const char *name)
 {
     RootedObject globalProto(cx, JS_GetFunctionPrototype(cx, global));
     RootedObject numFun(
         cx,
         JS_DefineObject(cx, global, name,
-                        (JSClass *) &NumericTypeClasses[type],
+                        (const JSClass *) &NumericTypeClasses[type],
                         globalProto, 0));
     if (!numFun)
         return false;
 
     RootedObject typeReprObj(cx, ScalarTypeRepresentation::Create(cx, type));
     if (!typeReprObj)
         return false;
 
@@ -1619,17 +1619,17 @@ js_InitTypedObjectClasses(JSContext *cx,
         return NULL;
 
     return global;
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // Binary blocks
 
-Class BinaryBlock::class_ = {
+const Class BinaryBlock::class_ = {
     "BinaryBlock",
     Class::NON_NATIVE |
     JSCLASS_HAS_RESERVED_SLOTS(BLOCK_RESERVED_SLOTS) |
     JSCLASS_HAS_PRIVATE |
     JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_CACHED_PROTO(JSProto_ArrayType),
     JS_PropertyStub,
     JS_DeletePropertyStub,
--- a/js/src/builtin/TypedObject.h
+++ b/js/src/builtin/TypedObject.h
@@ -42,41 +42,41 @@ enum BlockCommonSlots {
     // If this value is NULL, then the block instance owns the
     // uint8_t* in its priate data. Otherwise, this field contains the
     // owner, and thus keeps the owner alive.
     SLOT_BLOCKREFOWNER,
 
     BLOCK_RESERVED_SLOTS
 };
 
-extern Class DataClass;
+extern const Class DataClass;
 
-extern Class TypeClass;
+extern const Class TypeClass;
 
 template <ScalarTypeRepresentation::Type type, typename T>
 class NumericType
 {
   private:
-    static Class * typeToClass();
+    static const Class * typeToClass();
   public:
     static bool convert(JSContext *cx, HandleValue val, T* converted);
     static bool reify(JSContext *cx, void *mem, MutableHandleValue vp);
     static bool call(JSContext *cx, unsigned argc, Value *vp);
 };
 
-extern Class NumericTypeClasses[ScalarTypeRepresentation::TYPE_MAX];
+extern const Class NumericTypeClasses[ScalarTypeRepresentation::TYPE_MAX];
 
 /*
  * Type descriptor created by `new ArrayType(...)`
  */
 class ArrayType : public JSObject
 {
   private:
   public:
-    static Class class_;
+    static const Class class_;
 
     static JSObject *create(JSContext *cx, HandleObject arrayTypeGlobal,
                             HandleObject elementType, size_t length);
     static bool construct(JSContext *cx, unsigned int argc, jsval *vp);
     static bool repeat(JSContext *cx, unsigned int argc, jsval *vp);
 
     static bool toSource(JSContext *cx, unsigned int argc, jsval *vp);
 
@@ -94,17 +94,17 @@ class StructType : public JSObject
     /**
      * Sets up structType slots based on calculated memory size
      * and alignment and stores fieldmap as well.
      */
     static bool layout(JSContext *cx, HandleObject structType,
                        HandleObject fields);
 
   public:
-    static Class class_;
+    static const Class class_;
 
     static bool toSource(JSContext *cx, unsigned int argc, jsval *vp);
 
     static bool convertAndCopyTo(JSContext *cx,
                                  StructTypeRepresentation *typeRepr,
                                  HandleValue from, uint8_t *mem);
 
     static bool construct(JSContext *cx, unsigned int argc, jsval *vp);
@@ -190,17 +190,17 @@ class BinaryBlock
                                     bool *succeeded);
     static bool obj_deleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid,
                                     bool *succeeded);
 
     static bool obj_enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
                                 MutableHandleValue statep, MutableHandleId idp);
 
   public:
-    static Class class_;
+    static const Class class_;
 
     static bool isBlock(HandleObject val);
     static uint8_t *mem(HandleObject val);
 
     // creates zeroed memory of size of type
     static JSObject *createZeroed(JSContext *cx, HandleObject type);
 
     // creates a block that aliases the memory owned by `owner` at the
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -442,92 +442,92 @@ namespace UInt64 {
 }
 
 /*******************************************************************************
 ** JSClass definitions and initialization functions
 *******************************************************************************/
 
 // Class representing the 'ctypes' object itself. This exists to contain the
 // JSCTypesCallbacks set of function pointers.
-static JSClass sCTypesGlobalClass = {
+static const JSClass sCTypesGlobalClass = {
   "ctypes",
   JSCLASS_HAS_RESERVED_SLOTS(CTYPESGLOBAL_SLOTS),
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
-static JSClass sCABIClass = {
+static const JSClass sCABIClass = {
   "CABI",
   JSCLASS_HAS_RESERVED_SLOTS(CABI_SLOTS),
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
 // Class representing ctypes.{C,Pointer,Array,Struct,Function}Type.prototype.
 // This exists to give said prototypes a class of "CType", and to provide
 // reserved slots for stashing various other prototype objects.
-static JSClass sCTypeProtoClass = {
+static const JSClass sCTypeProtoClass = {
   "CType",
   JSCLASS_HAS_RESERVED_SLOTS(CTYPEPROTO_SLOTS),
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CType::FinalizeProtoClass,
   NULL, ConstructAbstract, NULL, ConstructAbstract
 };
 
 // Class representing ctypes.CData.prototype and the 'prototype' properties
 // of CTypes. This exists to give said prototypes a class of "CData".
-static JSClass sCDataProtoClass = {
+static const JSClass sCDataProtoClass = {
   "CData",
   0,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
-static JSClass sCTypeClass = {
+static const JSClass sCTypeClass = {
   "CType",
   JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(CTYPE_SLOTS),
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CType::Finalize,
   NULL, CType::ConstructData, CType::HasInstance, CType::ConstructData,
   CType::Trace
 };
 
-static JSClass sCDataClass = {
+static const JSClass sCDataClass = {
   "CData",
   JSCLASS_HAS_RESERVED_SLOTS(CDATA_SLOTS),
   JS_PropertyStub, JS_DeletePropertyStub, ArrayType::Getter, ArrayType::Setter,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CData::Finalize,
   NULL, FunctionType::Call, NULL, FunctionType::Call
 };
 
-static JSClass sCClosureClass = {
+static const JSClass sCClosureClass = {
   "CClosure",
   JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(CCLOSURE_SLOTS),
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CClosure::Finalize,
   NULL, NULL, NULL, NULL, CClosure::Trace
 };
 
 /*
  * Class representing the prototype of CDataFinalizer.
  */
-static JSClass sCDataFinalizerProtoClass = {
+static const JSClass sCDataFinalizerProtoClass = {
   "CDataFinalizer",
   0,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
 /*
  * Class representing instances of CDataFinalizer.
  *
  * Instances of CDataFinalizer have both private data (with type
  * |CDataFinalizer::Private|) and slots (see |CDataFinalizerSlots|).
  */
-static JSClass sCDataFinalizerClass = {
+static const JSClass sCDataFinalizerClass = {
   "CDataFinalizer",
   JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(CDATAFINALIZER_SLOTS),
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, CDataFinalizer::Finalize,
 };
 
 
 #define CTYPESFN_FLAGS \
@@ -677,38 +677,38 @@ static const JSPropertySpec sFunctionPro
 };
 
 static const JSFunctionSpec sFunctionInstanceFunctions[] = {
   JS_FN("call", js_fun_call, 1, CDATAFN_FLAGS),
   JS_FN("apply", js_fun_apply, 2, CDATAFN_FLAGS),
   JS_FS_END
 };
 
-static JSClass sInt64ProtoClass = {
+static const JSClass sInt64ProtoClass = {
   "Int64",
   0,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
-static JSClass sUInt64ProtoClass = {
+static const JSClass sUInt64ProtoClass = {
   "UInt64",
   0,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
-static JSClass sInt64Class = {
+static const JSClass sInt64Class = {
   "Int64",
   JSCLASS_HAS_RESERVED_SLOTS(INT64_SLOTS),
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Int64Base::Finalize
 };
 
-static JSClass sUInt64Class = {
+static const JSClass sUInt64Class = {
   "UInt64",
   JSCLASS_HAS_RESERVED_SLOTS(INT64_SLOTS),
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Int64Base::Finalize
 };
 
 static const JSFunctionSpec sInt64StaticFunctions[] = {
   JS_FN("compare", Int64::Compare, 2, CTYPESFN_FLAGS),
@@ -1008,17 +1008,17 @@ InitTypeConstructor(JSContext* cx,
     return false;
 
   return true;
 }
 
 static JSObject*
 InitInt64Class(JSContext* cx,
                HandleObject parent,
-               JSClass* clasp,
+               const JSClass* clasp,
                JSNative construct,
                const JSFunctionSpec* fs,
                const JSFunctionSpec* static_fs)
 {
   // Init type class and constructor
   RootedObject prototype(cx, JS_InitClass(cx, parent, NULL, clasp, construct,
                                           0, NULL, fs, NULL, static_fs));
   if (!prototype)
@@ -7282,17 +7282,17 @@ CDataFinalizer::Cleanup(CDataFinalizer::
 *******************************************************************************/
 
 JSObject*
 Int64Base::Construct(JSContext* cx,
                      HandleObject proto,
                      uint64_t data,
                      bool isUnsigned)
 {
-  JSClass* clasp = isUnsigned ? &sUInt64Class : &sInt64Class;
+  const JSClass* clasp = isUnsigned ? &sUInt64Class : &sInt64Class;
   RootedObject parent(cx, JS_GetParent(proto));
   RootedObject result(cx, JS_NewObject(cx, clasp, proto, parent));
   if (!result)
     return NULL;
 
   // attach the Int64's data
   uint64_t* buffer = cx->new_<uint64_t>(data);
   if (!buffer) {
--- a/js/src/ctypes/Library.cpp
+++ b/js/src/ctypes/Library.cpp
@@ -28,17 +28,17 @@ namespace Library
 }
 
 /*******************************************************************************
 ** JSObject implementation
 *******************************************************************************/
 
 typedef Rooted<JSFlatString*>    RootedFlatString;
 
-static JSClass sLibraryClass = {
+static const JSClass sLibraryClass = {
   "Library",
   JSCLASS_HAS_RESERVED_SLOTS(LIBRARY_SLOTS),
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub,JS_ResolveStub, JS_ConvertStub, Library::Finalize
 };
 
 #define CTYPESFN_FLAGS \
   (JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -1458,17 +1458,17 @@ GCMarker::processMarkStackTop(SliceBudge
 
         types::TypeObject *type = obj->typeFromGC();
         PushMarkStack(this, type);
 
         Shape *shape = obj->lastProperty();
         PushMarkStack(this, shape);
 
         /* Call the trace hook if necessary. */
-        Class *clasp = type->clasp;
+        const Class *clasp = type->clasp;
         if (clasp->trace) {
             JS_ASSERT_IF(runtime->gcMode == JSGC_MODE_INCREMENTAL &&
                          runtime->gcIncrementalEnabled,
                          clasp->flags & JSCLASS_IMPLEMENTS_BARRIERS);
             clasp->trace(this, obj);
         }
 
         if (!shape->isNative())
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -356,17 +356,17 @@ js::Nursery::collectToFixedPoint(MinorCo
         JSObject *obj = static_cast<JSObject*>(p->forwardingAddress());
         traceObject(trc, obj);
     }
 }
 
 JS_ALWAYS_INLINE void
 js::Nursery::traceObject(MinorCollectionTracer *trc, JSObject *obj)
 {
-    Class *clasp = obj->getClass();
+    const Class *clasp = obj->getClass();
     if (clasp->trace)
         clasp->trace(trc, obj);
 
     if (!obj->isNative())
         return;
 
     if (!obj->hasEmptyElements())
         markSlots(trc, obj->getDenseElements(), obj->getDenseInitializedLength());
--- a/js/src/gdb/gdb-tests.cpp
+++ b/js/src/gdb/gdb-tests.cpp
@@ -8,17 +8,17 @@
 
 #include "gdb-tests.h"
 #include "jsapi.h"
 #include "jsfriendapi.h"
 
 using namespace JS;
 
 /* The class of the global object. */
-JSClass global_class = {
+const JSClass global_class = {
     "global", JSCLASS_GLOBAL_FLAGS,
     JS_PropertyStub,  JS_DeletePropertyStub, JS_PropertyStub,  JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
 template<typename T>
 inline T *
 checkPtr(T *ptr)
--- a/js/src/jit/AsmJSModule.cpp
+++ b/js/src/jit/AsmJSModule.cpp
@@ -160,17 +160,17 @@ AsmJSModuleObject_finalize(FreeOp *fop, 
 }
 
 static void
 AsmJSModuleObject_trace(JSTracer *trc, JSObject *obj)
 {
     obj->as<AsmJSModuleObject>().module().trace(trc);
 }
 
-Class AsmJSModuleObject::class_ = {
+const Class AsmJSModuleObject::class_ = {
     "AsmJSModuleObject",
     JSCLASS_IS_ANONYMOUS | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(AsmJSModuleObject::RESERVED_SLOTS),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
--- a/js/src/jit/AsmJSModule.h
+++ b/js/src/jit/AsmJSModule.h
@@ -727,16 +727,16 @@ class AsmJSModuleObject : public JSObjec
 
     AsmJSModule &module() const;
 
     void sizeOfMisc(mozilla::MallocSizeOf mallocSizeOf, size_t *asmJSModuleCode,
                     size_t *asmJSModuleData) {
         module().sizeOfMisc(mallocSizeOf, asmJSModuleCode, asmJSModuleData);
     }
 
-    static Class class_;
+    static const Class class_;
 };
 
 }  // namespace js
 
 #endif  // JS_ION
 
 #endif /* jit_AsmJSModule_h */
--- a/js/src/jit/BaselineIC.cpp
+++ b/js/src/jit/BaselineIC.cpp
@@ -4429,17 +4429,17 @@ ICGetElem_Arguments::Compiler::generateS
         EmitStubGuardFailure(masm);
         return true;
     }
 
     JS_ASSERT(which_ == ICGetElem_Arguments::Strict ||
               which_ == ICGetElem_Arguments::Normal);
 
     bool isStrict = which_ == ICGetElem_Arguments::Strict;
-    Class *clasp = isStrict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
+    const Class *clasp = isStrict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
 
     GeneralRegisterSet regs(availableGeneralRegs(2));
     Register scratchReg = regs.takeAny();
 
     // Guard on input being an arguments object.
     masm.branchTestObject(Assembler::NotEqual, R0, &failure);
     Register objReg = masm.extractObject(R0, ExtractTemp0);
     masm.branchTestObjClass(Assembler::NotEqual, objReg, scratchReg, clasp, &failure);
@@ -6633,17 +6633,17 @@ ICGetProp_ArgumentsLength::Compiler::gen
         masm.bind(&failure);
         EmitStubGuardFailure(masm);
         return true;
     }
     JS_ASSERT(which_ == ICGetProp_ArgumentsLength::Strict ||
               which_ == ICGetProp_ArgumentsLength::Normal);
 
     bool isStrict = which_ == ICGetProp_ArgumentsLength::Strict;
-    Class *clasp = isStrict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
+    const Class *clasp = isStrict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
 
     Register scratchReg = R1.scratchReg();
 
     // Guard on input being an arguments object.
     masm.branchTestObject(Assembler::NotEqual, R0, &failure);
     Register objReg = masm.extractObject(R0, ExtractTemp0);
     masm.branchTestObjClass(Assembler::NotEqual, objReg, scratchReg, clasp, &failure);
 
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -7667,17 +7667,17 @@ IonBuilder::jsop_not()
     MNot *ins = new MNot(value);
     current->add(ins);
     current->push(ins);
     ins->infer(cx);
     return true;
 }
 
 inline bool
-TestClassHasAccessorHook(Class *clasp, bool isGetter)
+TestClassHasAccessorHook(const Class *clasp, bool isGetter)
 {
     if (isGetter && clasp->ops.getGeneric)
         return true;
     if (!isGetter && clasp->ops.setGeneric)
         return true;
     return false;
 }
 
--- a/js/src/jit/IonCaches.cpp
+++ b/js/src/jit/IonCaches.cpp
@@ -1616,18 +1616,18 @@ GetPropertyIC::tryAttachArgumentsLength(
     if (output().hasValue()) {
         tmpReg = output().valueReg().scratchReg();
     } else {
         JS_ASSERT(output().type() == MIRType_Int32);
         tmpReg = output().typedReg().gpr();
     }
     JS_ASSERT(object() != tmpReg);
 
-    Class *clasp = obj->is<StrictArgumentsObject>() ? &StrictArgumentsObject::class_
-                                                    : &NormalArgumentsObject::class_;
+    const Class *clasp = obj->is<StrictArgumentsObject>() ? &StrictArgumentsObject::class_
+                                                          : &NormalArgumentsObject::class_;
 
     Label fail;
     Label pass;
     masm.branchTestObjClass(Assembler::NotEqual, object(), tmpReg, clasp, &failures);
 
     // Get initial ArgsObj length value, test if length has been overridden.
     masm.unboxInt32(Address(object(), ArgumentsObject::getInitialLengthSlotOffset()), tmpReg);
     masm.branchTest32(Assembler::NonZero, tmpReg, Imm32(ArgumentsObject::LENGTH_OVERRIDDEN_BIT),
@@ -3063,18 +3063,18 @@ GetElementIC::attachArgumentsElement(JSC
 
     Label failures;
     MacroAssembler masm(cx);
     RepatchStubAppender attacher(*this);
 
     Register tmpReg = output().scratchReg().gpr();
     JS_ASSERT(tmpReg != InvalidReg);
 
-    Class *clasp = obj->is<StrictArgumentsObject>() ? &StrictArgumentsObject::class_
-                                                    : &NormalArgumentsObject::class_;
+    const Class *clasp = obj->is<StrictArgumentsObject>() ? &StrictArgumentsObject::class_
+                                                          : &NormalArgumentsObject::class_;
 
     Label fail;
     Label pass;
     masm.branchTestObjClass(Assembler::NotEqual, object(), tmpReg, clasp, &failures);
 
     // Get initial ArgsObj length value, test if length has been overridden.
     masm.unboxInt32(Address(object(), ArgumentsObject::getInitialLengthSlotOffset()), tmpReg);
     masm.branchTest32(Assembler::NonZero, tmpReg, Imm32(ArgumentsObject::LENGTH_OVERRIDDEN_BIT),
--- a/js/src/jit/IonMacroAssembler.h
+++ b/js/src/jit/IonMacroAssembler.h
@@ -176,17 +176,17 @@ class MacroAssembler : public MacroAssem
         loadPtr(Address(objReg, JSObject::offsetOfShape()), dest);
 
         loadPtr(Address(dest, Shape::offsetOfBase()), dest);
     }
     void loadObjClass(Register objReg, Register dest) {
         loadPtr(Address(objReg, JSObject::offsetOfType()), dest);
         loadPtr(Address(dest, offsetof(types::TypeObject, clasp)), dest);
     }
-    void branchTestObjClass(Condition cond, Register obj, Register scratch, js::Class *clasp,
+    void branchTestObjClass(Condition cond, Register obj, Register scratch, const js::Class *clasp,
                             Label *label) {
         loadPtr(Address(obj, JSObject::offsetOfType()), scratch);
         branchPtr(cond, Address(scratch, offsetof(types::TypeObject, clasp)), ImmWord(clasp), label);
     }
     void branchTestObjShape(Condition cond, Register obj, const Shape *shape, Label *label) {
         branchPtr(cond, Address(obj, JSObject::offsetOfShape()), ImmGCPtr(shape), label);
     }
     void branchTestObjShape(Condition cond, Register obj, Register shape, Label *label) {
--- a/js/src/jit/MCallOptimize.cpp
+++ b/js/src/jit/MCallOptimize.cpp
@@ -997,17 +997,17 @@ IonBuilder::inlineRegExpTest(CallInfo &c
 
     // TI can infer a NULL return type of regexp_test with eager compilation.
     if (CallResultEscapes(pc) && getInlineReturnType() != MIRType_Boolean)
         return InliningStatus_NotInlined;
 
     if (callInfo.thisArg()->type() != MIRType_Object)
         return InliningStatus_NotInlined;
     types::StackTypeSet *thisTypes = callInfo.thisArg()->resultTypeSet();
-    Class *clasp = thisTypes ? thisTypes->getKnownClass() : NULL;
+    const Class *clasp = thisTypes ? thisTypes->getKnownClass() : NULL;
     if (clasp != &RegExpObject::class_)
         return InliningStatus_NotInlined;
     if (callInfo.getArg(0)->type() != MIRType_String)
         return InliningStatus_NotInlined;
 
     callInfo.unwrapArgs();
 
     MInstruction *match = MRegExpTest::New(callInfo.thisArg(), callInfo.getArg(0));
@@ -1473,18 +1473,18 @@ IonBuilder::inlineHaveSameClass(CallInfo
         return InliningStatus_NotInlined;
     if (callInfo.getArg(0)->type() != MIRType_Object)
         return InliningStatus_NotInlined;
     if (callInfo.getArg(1)->type() != MIRType_Object)
         return InliningStatus_NotInlined;
 
     types::StackTypeSet *arg1Types = callInfo.getArg(0)->resultTypeSet();
     types::StackTypeSet *arg2Types = callInfo.getArg(1)->resultTypeSet();
-    Class *arg1Clasp = arg1Types ? arg1Types->getKnownClass() : NULL;
-    Class *arg2Clasp = arg2Types ? arg2Types->getKnownClass() : NULL;
+    const Class *arg1Clasp = arg1Types ? arg1Types->getKnownClass() : NULL;
+    const Class *arg2Clasp = arg2Types ? arg2Types->getKnownClass() : NULL;
     if (arg1Clasp && arg2Clasp) {
         MConstant *constant = MConstant::New(BooleanValue(arg1Clasp == arg2Clasp));
         current->add(constant);
         current->push(constant);
         return InliningStatus_Inlined;
     }
 
     callInfo.unwrapArgs();
@@ -1511,17 +1511,17 @@ IonBuilder::inlineIsCallable(CallInfo &c
     // all, and if we know the class check if it is callable.
     bool isCallableKnown = false;
     bool isCallableConstant;
     if (callInfo.getArg(0)->type() != MIRType_Object) {
         isCallableKnown = true;
         isCallableConstant = false;
     } else {
         types::StackTypeSet *types = callInfo.getArg(0)->resultTypeSet();
-        Class *clasp = types ? types->getKnownClass() : NULL;
+        const Class *clasp = types ? types->getKnownClass() : NULL;
         if (clasp) {
             isCallableKnown = true;
             isCallableConstant = clasp->isCallable();
         }
     }
 
     if (isCallableKnown) {
         MConstant *constant = MConstant::New(BooleanValue(isCallableConstant));
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -2635,17 +2635,17 @@ jit::ElementAccessIsDenseNative(MDefinit
 
     if (id->type() != MIRType_Int32 && id->type() != MIRType_Double)
         return false;
 
     types::StackTypeSet *types = obj->resultTypeSet();
     if (!types)
         return false;
 
-    Class *clasp = types->getKnownClass();
+    const Class *clasp = types->getKnownClass();
     return clasp && clasp->isNative();
 }
 
 bool
 jit::ElementAccessIsTypedArray(MDefinition *obj, MDefinition *id,
                                ScalarTypeRepresentation::Type *arrayType)
 {
     if (obj->mightBeType(MIRType_String))
--- a/js/src/jsapi-tests/README
+++ b/js/src/jsapi-tests/README
@@ -124,17 +124,17 @@ tests.h:
 --- Custom test setup
 
 Before executing each test, the test framework calls the tests' init() member
 function, which populates the rt, cx, and global member variables.
 
 A test can customize the test setup process by overloading virtual member
 functions, like this:
 
-    JSClass globalClassWithResolve = { ... };
+    const JSClass globalClassWithResolve = { ... };
 
     BEGIN_TEST(testGlobalResolveHook)
         {
             RootedValue v;
             EVAL("v", v.address());
             CHECK_SAME(v, JSVAL_VOID);
             return true;
         }
--- a/js/src/jsapi-tests/testAddPropertyPropcache.cpp
+++ b/js/src/jsapi-tests/testAddPropertyPropcache.cpp
@@ -14,17 +14,17 @@ static int callCount = 0;
 
 static bool
 addProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp)
 {
   callCount++;
   return true;
 }
 
-JSClass addPropertyClass = {
+const JSClass addPropertyClass = {
     "AddPropertyTester",
     0,
     addProperty,
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
+++ b/js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsapi-tests/tests.h"
 
 using namespace JS;
 
-static JSClass CustomClass = {
+static const JSClass CustomClass = {
   "CustomClass",
   JSCLASS_HAS_RESERVED_SLOTS(1),
   JS_PropertyStub,
   JS_DeletePropertyStub,
   JS_PropertyStub,
   JS_StrictPropertyStub,
   JS_EnumerateStub,
   JS_ResolveStub,
--- a/js/src/jsapi-tests/testChromeBuffer.cpp
+++ b/js/src/jsapi-tests/testChromeBuffer.cpp
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsapi-tests/tests.h"
 
 JSPrincipals system_principals = {
     1
 };
 
-JSClass global_class = {
+const JSClass global_class = {
     "global",
     JSCLASS_IS_GLOBAL | JSCLASS_GLOBAL_FLAGS,
     JS_PropertyStub,
     JS_DeletePropertyStub,
     JS_PropertyStub,
     JS_StrictPropertyStub,
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/jsapi-tests/testClassGetter.cpp
+++ b/js/src/jsapi-tests/testClassGetter.cpp
@@ -16,17 +16,17 @@ static bool test_prop_get( JSContext *cx
 {
     called_test_prop_get++;
     return true;
 }
 
 static bool
 PTest(JSContext* cx, unsigned argc, jsval *vp);
 
-static JSClass ptestClass = {
+static const JSClass ptestClass = {
     "PTest",
     JSCLASS_HAS_PRIVATE,
 
     JS_PropertyStub,       // add
     JS_DeletePropertyStub, // delete
     test_prop_get,         // get
     JS_StrictPropertyStub, // set
     JS_EnumerateStub,
--- a/js/src/jsapi-tests/testCustomIterator.cpp
+++ b/js/src/jsapi-tests/testCustomIterator.cpp
@@ -22,17 +22,17 @@ IterHook(JSContext *cx, JS::HandleObject
     JS::RootedObject iterObj(cx, JS_NewObject(cx, NULL, NULL, NULL));
     if (!iterObj)
         return NULL;
     if (!JS_DefineFunction(cx, iterObj, "next", IterNext, 0, 0))
         return NULL;
     return iterObj;
 }
 
-js::Class HasCustomIterClass = {
+const js::Class HasCustomIterClass = {
     "HasCustomIter",
     0,
     JS_PropertyStub,
     JS_DeletePropertyStub,
     JS_PropertyStub,
     JS_StrictPropertyStub,
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/jsapi-tests/testLookup.cpp
+++ b/js/src/jsapi-tests/testLookup.cpp
@@ -32,17 +32,17 @@ BEGIN_TEST(testLookup_bug522590)
     JSObject *funobj = &r.toObject();
     CHECK(funobj->is<JSFunction>());
     CHECK(!js::IsInternalFunctionObject(funobj));
 
     return true;
 }
 END_TEST(testLookup_bug522590)
 
-static JSClass DocumentAllClass = {
+static const JSClass DocumentAllClass = {
     "DocumentAll",
     JSCLASS_EMULATES_UNDEFINED,
     JS_PropertyStub,
     JS_DeletePropertyStub,
     JS_PropertyStub,
     JS_StrictPropertyStub,
     JS_EnumerateStub,
     JS_ResolveStub,
@@ -71,17 +71,17 @@ document_resolve(JSContext *cx, JS::Hand
             objp.set(ok ? obj.get() : NULL);
             return ok;
         }
     }
     objp.set(NULL);
     return true;
 }
 
-static JSClass document_class = {
+static const JSClass document_class = {
     "document", JSCLASS_NEW_RESOLVE,
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, (JSResolveOp) document_resolve, JS_ConvertStub
 };
 
 BEGIN_TEST(testLookup_bug570195)
 {
     JS::RootedObject obj(cx, JS_NewObject(cx, &document_class, NULL, NULL));
--- a/js/src/jsapi-tests/testNewObject.cpp
+++ b/js/src/jsapi-tests/testNewObject.cpp
@@ -87,17 +87,17 @@ BEGIN_TEST(testNewObject_1)
     rt = OBJECT_TO_JSVAL(obj);
     CHECK(JS_IsArrayObject(cx, obj));
     CHECK(JS_GetArrayLength(cx, obj, &len));
     CHECK_EQUAL(len, N);
     CHECK(JS_GetElement(cx, obj, N - 1, &v));
     CHECK_SAME(v, INT_TO_JSVAL(N - 1));
 
     // With JSClass.construct.
-    static JSClass cls = {
+    static const JSClass cls = {
         "testNewObject_1",
         0,
         JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
         JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
         NULL, NULL, NULL, constructHook
     };
     JS::RootedObject ctor(cx, JS_NewObject(cx, &cls, NULL, NULL));
     CHECK(ctor);
--- a/js/src/jsapi-tests/testObjectEmulatingUndefined.cpp
+++ b/js/src/jsapi-tests/testObjectEmulatingUndefined.cpp
@@ -1,15 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "jsapi-tests/tests.h"
 
-static JSClass ObjectEmulatingUndefinedClass = {
+static const JSClass ObjectEmulatingUndefinedClass = {
     "ObjectEmulatingUndefined",
     JSCLASS_EMULATES_UNDEFINED,
     JS_PropertyStub,
     JS_DeletePropertyStub,
     JS_PropertyStub,
     JS_StrictPropertyStub,
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/jsapi-tests/testOps.cpp
+++ b/js/src/jsapi-tests/testOps.cpp
@@ -14,17 +14,17 @@ my_convert(JSContext* context, JS::Handl
 {
     if (type == JSTYPE_VOID || type == JSTYPE_STRING || type == JSTYPE_NUMBER || type == JSTYPE_BOOLEAN) {
         rval.set(JS_NumberValue(123));
         return true;
     }
     return false;
 }
 
-static JSClass myClass = {
+static const JSClass myClass = {
     "MyClass",
     0,
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, my_convert
 };
 
 static bool
 createMyObject(JSContext* context, unsigned argc, jsval *vp)
--- a/js/src/jsapi-tests/testProfileStrings.cpp
+++ b/js/src/jsapi-tests/testProfileStrings.cpp
@@ -20,17 +20,17 @@ reset(JSContext *cx)
 {
     psize = max_stack = 0;
     memset(pstack, 0, sizeof(pstack));
     cx->runtime()->spsProfiler.stringsReset();
     cx->runtime()->spsProfiler.enableSlowAssertions(true);
     js::EnableRuntimeProfilingStack(cx->runtime(), true);
 }
 
-static JSClass ptestClass = {
+static const JSClass ptestClass = {
     "Prof", 0, JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub,
     JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
 static bool
 test_fn(JSContext *cx, unsigned argc, jsval *vp)
 {
     max_stack = psize;
--- a/js/src/jsapi-tests/testPropCache.cpp
+++ b/js/src/jsapi-tests/testPropCache.cpp
@@ -11,17 +11,17 @@ static int g_counter;
 
 static bool
 CounterAdd(JSContext *cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp)
 {
     g_counter++;
     return true;
 }
 
-static JSClass CounterClass = {
+static const JSClass CounterClass = {
     "Counter",  /* name */
     0,  /* flags */
     CounterAdd, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
 BEGIN_TEST(testPropCache_bug505798)
 {
--- a/js/src/jsapi-tests/testResolveRecursion.cpp
+++ b/js/src/jsapi-tests/testResolveRecursion.cpp
@@ -9,17 +9,17 @@
 
 /*
  * Test that resolve hook recursion for the same object and property is
  * prevented.
  */
 
 BEGIN_TEST(testResolveRecursion)
 {
-    static JSClass my_resolve_class = {
+    static const JSClass my_resolve_class = {
         "MyResolve",
         JSCLASS_NEW_RESOLVE | JSCLASS_HAS_PRIVATE,
 
         JS_PropertyStub,       // add
         JS_DeletePropertyStub, // delete
         JS_PropertyStub,       // get
         JS_StrictPropertyStub, // set
         JS_EnumerateStub,
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -220,18 +220,18 @@ class JSAPITest
         }
         fprintf(stderr, "%s:%d:%.*s\n", filename, lineno, (int) msg.length(), msg.begin());
         msgs += msg;
         return false;
     }
 
     JSAPITestString messages() const { return msgs; }
 
-    static JSClass * basicGlobalClass() {
-        static JSClass c = {
+    static const JSClass * basicGlobalClass() {
+        static const JSClass c = {
             "global", JSCLASS_GLOBAL_FLAGS,
             JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
             JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
         };
         return &c;
     }
 
   protected:
@@ -301,17 +301,17 @@ class JSAPITest
         JSContext *cx = JS_NewContext(rt, 8192);
         if (!cx)
             return NULL;
         JS_SetOptions(cx, JSOPTION_VAROBJFIX);
         JS_SetErrorReporter(cx, &reportError);
         return cx;
     }
 
-    virtual JSClass * getGlobalClass() {
+    virtual const JSClass * getGlobalClass() {
         return basicGlobalClass();
     }
 
     virtual JSObject * createGlobal(JSPrincipals *principals = NULL);
 };
 
 #define BEGIN_TEST(testname)                                            \
     class cls_##testname : public JSAPITest {                           \
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1323,17 +1323,17 @@ JS_InitStandardClasses(JSContext *cx, JS
 #define EAGER_ATOM(name)            NAME_OFFSET(name)
 #define EAGER_CLASS_ATOM(name)      NAME_OFFSET(name)
 #define EAGER_ATOM_AND_CLASP(name)  EAGER_CLASS_ATOM(name), CLASP(name)
 #define EAGER_ATOM_AND_OCLASP(name) EAGER_CLASS_ATOM(name), OCLASP(name)
 
 typedef struct JSStdName {
     ClassInitializerOp init;
     size_t      atomOffset;     /* offset of atom pointer in JSAtomState */
-    Class       *clasp;
+    const Class *clasp;
 } JSStdName;
 
 static Handle<PropertyName*>
 StdNameToPropertyName(JSContext *cx, const JSStdName *stdn)
 {
     return OFFSET_TO_NAME(cx->runtime(), stdn->atomOffset);
 }
 
@@ -2487,17 +2487,17 @@ JS_ConvertStub(JSContext *cx, HandleObje
 {
     JS_ASSERT(type != JSTYPE_OBJECT && type != JSTYPE_FUNCTION);
     JS_ASSERT(obj);
     return DefaultValue(cx, obj, type, vp);
 }
 
 JS_PUBLIC_API(JSObject *)
 JS_InitClass(JSContext *cx, JSObject *objArg, JSObject *parent_protoArg,
-             JSClass *clasp, JSNative constructor, unsigned nargs,
+             const JSClass *clasp, JSNative constructor, unsigned nargs,
              const JSPropertySpec *ps, const JSFunctionSpec *fs,
              const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs)
 {
     RootedObject obj(cx, objArg);
     RootedObject parent_proto(cx, parent_protoArg);
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, parent_proto);
@@ -2508,24 +2508,24 @@ JS_InitClass(JSContext *cx, JSObject *ob
 JS_PUBLIC_API(bool)
 JS_LinkConstructorAndPrototype(JSContext *cx, JSObject *ctorArg, JSObject *protoArg)
 {
     RootedObject ctor(cx, ctorArg);
     RootedObject proto(cx, protoArg);
     return LinkConstructorAndPrototype(cx, ctor, proto);
 }
 
-JS_PUBLIC_API(JSClass *)
+JS_PUBLIC_API(const JSClass *)
 JS_GetClass(JSObject *obj)
 {
     return obj->getJSClass();
 }
 
 JS_PUBLIC_API(bool)
-JS_InstanceOf(JSContext *cx, JSObject *objArg, JSClass *clasp, jsval *argv)
+JS_InstanceOf(JSContext *cx, JSObject *objArg, const JSClass *clasp, jsval *argv)
 {
     RootedObject obj(cx, objArg);
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 #ifdef DEBUG
     if (argv) {
         assertSameCompartment(cx, obj);
         assertSameCompartment(cx, JSValueArray(argv - 2, 2));
@@ -2560,17 +2560,17 @@ JS_GetPrivate(JSObject *obj)
 JS_PUBLIC_API(void)
 JS_SetPrivate(JSObject *obj, void *data)
 {
     /* This function can be called by a finalizer. */
     obj->setPrivate(data);
 }
 
 JS_PUBLIC_API(void *)
-JS_GetInstancePrivate(JSContext *cx, JSObject *objArg, JSClass *clasp, jsval *argv)
+JS_GetInstancePrivate(JSContext *cx, JSObject *objArg, const JSClass *clasp, jsval *argv)
 {
     RootedObject obj(cx, objArg);
     if (!JS_InstanceOf(cx, obj, clasp, argv))
         return NULL;
     return obj->getPrivate();
 }
 
 JS_PUBLIC_API(bool)
@@ -2662,17 +2662,17 @@ class AutoHoldZone
   private:
     bool *holdp;
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 } /* anonymous namespace */
 
 JS_PUBLIC_API(JSObject *)
-JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals,
+JS_NewGlobalObject(JSContext *cx, const JSClass *clasp, JSPrincipals *principals,
                    JS::OnNewGlobalHookOption hookOption,
                    const JS::CompartmentOptions &options)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     JS_ASSERT(!cx->isExceptionPending());
 
@@ -2719,26 +2719,26 @@ JS_FireOnNewGlobalObject(JSContext *cx, 
     // to be able to throw errors during delicate global creation routines.
     // This infallibility will eat OOM and slow script, but if that happens
     // we'll likely run up into them again soon in a fallible context.
     Rooted<js::GlobalObject*> globalObject(cx, &global->as<GlobalObject>());
     Debugger::onNewGlobalObject(cx, globalObject);
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_NewObject(JSContext *cx, JSClass *jsclasp, JSObject *protoArg, JSObject *parentArg)
+JS_NewObject(JSContext *cx, const JSClass *jsclasp, JSObject *protoArg, JSObject *parentArg)
 {
     RootedObject proto(cx, protoArg);
     RootedObject parent(cx, parentArg);
     JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, proto, parent);
 
-    Class *clasp = Valueify(jsclasp);
+    const Class *clasp = Valueify(jsclasp);
     if (!clasp)
         clasp = &JSObject::class_;    /* default class is Object */
 
     JS_ASSERT(clasp != &JSFunction::class_);
     JS_ASSERT(!(clasp->flags & JSCLASS_IS_GLOBAL));
 
     JSObject *obj = NewObjectWithClassProto(cx, clasp, proto, parent);
     if (obj) {
@@ -2749,40 +2749,40 @@ JS_NewObject(JSContext *cx, JSClass *jsc
             MarkTypeObjectFlags(cx, obj, flags);
     }
 
     JS_ASSERT_IF(obj, obj->getParent());
     return obj;
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_NewObjectWithGivenProto(JSContext *cx, JSClass *jsclasp, JSObject *protoArg, JSObject *parentArg)
+JS_NewObjectWithGivenProto(JSContext *cx, const JSClass *jsclasp, JSObject *protoArg, JSObject *parentArg)
 {
     RootedObject proto(cx, protoArg);
     RootedObject parent(cx, parentArg);
     JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, proto, parent);
 
-    Class *clasp = Valueify(jsclasp);
+    const Class *clasp = Valueify(jsclasp);
     if (!clasp)
         clasp = &JSObject::class_;    /* default class is Object */
 
     JS_ASSERT(clasp != &JSFunction::class_);
     JS_ASSERT(!(clasp->flags & JSCLASS_IS_GLOBAL));
 
     JSObject *obj = NewObjectWithGivenProto(cx, clasp, proto, parent);
     if (obj)
         MarkTypeObjectUnknownProperties(cx, obj->type());
     return obj;
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_NewObjectForConstructor(JSContext *cx, JSClass *clasp, const jsval *vp)
+JS_NewObjectForConstructor(JSContext *cx, const JSClass *clasp, const jsval *vp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, *vp);
 
     RootedObject obj(cx, JSVAL_TO_OBJECT(*vp));
     return CreateThis(cx, Valueify(clasp), obj);
 }
@@ -3285,26 +3285,26 @@ JS_DefineOwnProperty(JSContext *cx, JSOb
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, id, descriptor);
 
     return DefineOwnProperty(cx, obj, id, descriptor, bp);
 }
 
 JS_PUBLIC_API(JSObject *)
-JS_DefineObject(JSContext *cx, JSObject *objArg, const char *name, JSClass *jsclasp,
+JS_DefineObject(JSContext *cx, JSObject *objArg, const char *name, const JSClass *jsclasp,
                 JSObject *protoArg, unsigned attrs)
 {
     RootedObject obj(cx, objArg);
     RootedObject proto(cx, protoArg);
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, proto);
 
-    Class *clasp = Valueify(jsclasp);
+    const Class *clasp = Valueify(jsclasp);
     if (!clasp)
         clasp = &JSObject::class_;    /* default class is Object */
 
     RootedObject nobj(cx, NewObjectWithClassProto(cx, clasp, proto, obj));
     if (!nobj)
         return NULL;
 
     if (!DefineProperty(cx, obj, name, ObjectValue(*nobj), GetterWrapper(NULL),
@@ -3711,17 +3711,17 @@ JS_SetAllNonReservedSlotsToUndefined(JSC
     RootedObject obj(cx, objArg);
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
 
     if (!obj->isNative())
         return;
 
-    Class *clasp = obj->getClass();
+    const Class *clasp = obj->getClass();
     unsigned numReserved = JSCLASS_RESERVED_SLOTS(clasp);
     unsigned numSlots = obj->slotSpan();
     for (unsigned i = numReserved; i < numSlots; i++)
         obj->setSlot(i, UndefinedValue());
 }
 
 JS_PUBLIC_API(JSIdArray *)
 JS_Enumerate(JSContext *cx, JSObject *objArg)
@@ -3779,17 +3779,17 @@ prop_iter_trace(JSTracer *trc, JSObject 
         obj->setPrivateUnbarriered(tmp);
     } else {
         /* Non-native case: mark each id in the JSIdArray private. */
         JSIdArray *ida = (JSIdArray *) pdata;
         MarkIdRange(trc, ida->length, ida->vector, "prop iter");
     }
 }
 
-static Class prop_iter_class = {
+static const Class prop_iter_class = {
     "PropertyIterator",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(1),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -2413,44 +2413,44 @@ struct JSFunctionSpec {
     {name, JSOP_WRAPPER(call), nargs, flags}
 #define JS_FN(name,call,nargs,flags)                                          \
     {name, JSOP_WRAPPER(call), nargs, (flags) | JSFUN_STUB_GSOPS}
 #define JS_FNINFO(name,call,info,nargs,flags)                                 \
     {name,{call,info},nargs,flags}
 
 extern JS_PUBLIC_API(JSObject *)
 JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto,
-             JSClass *clasp, JSNative constructor, unsigned nargs,
+             const JSClass *clasp, JSNative constructor, unsigned nargs,
              const JSPropertySpec *ps, const JSFunctionSpec *fs,
              const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs);
 
 /*
  * Set up ctor.prototype = proto and proto.constructor = ctor with the
  * right property flags.
  */
 extern JS_PUBLIC_API(bool)
 JS_LinkConstructorAndPrototype(JSContext *cx, JSObject *ctor, JSObject *proto);
 
-extern JS_PUBLIC_API(JSClass *)
+extern JS_PUBLIC_API(const JSClass *)
 JS_GetClass(JSObject *obj);
 
 extern JS_PUBLIC_API(bool)
-JS_InstanceOf(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv);
+JS_InstanceOf(JSContext *cx, JSObject *obj, const JSClass *clasp, jsval *argv);
 
 extern JS_PUBLIC_API(bool)
 JS_HasInstance(JSContext *cx, JSObject *obj, jsval v, bool *bp);
 
 extern JS_PUBLIC_API(void *)
 JS_GetPrivate(JSObject *obj);
 
 extern JS_PUBLIC_API(void)
 JS_SetPrivate(JSObject *obj, void *data);
 
 extern JS_PUBLIC_API(void *)
-JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp,
+JS_GetInstancePrivate(JSContext *cx, JSObject *obj, const JSClass *clasp,
                       jsval *argv);
 
 extern JS_PUBLIC_API(bool)
 JS_GetPrototype(JSContext *cx, JS::Handle<JSObject*> obj, JS::MutableHandle<JSObject*> protop);
 
 extern JS_PUBLIC_API(bool)
 JS_SetPrototype(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<JSObject*> proto);
 
@@ -2538,42 +2538,42 @@ struct JS_PUBLIC_API(CompartmentOptions)
 enum OnNewGlobalHookOption {
     FireOnNewGlobalHook,
     DontFireOnNewGlobalHook
 };
 
 } /* namespace JS */
 
 extern JS_PUBLIC_API(JSObject *)
-JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals,
+JS_NewGlobalObject(JSContext *cx, const JSClass *clasp, JSPrincipals *principals,
                    JS::OnNewGlobalHookOption hookOption,
                    const JS::CompartmentOptions &options = JS::CompartmentOptions());
 
 extern JS_PUBLIC_API(void)
 JS_FireOnNewGlobalObject(JSContext *cx, JS::HandleObject global);
 
 extern JS_PUBLIC_API(JSObject *)
-JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
+JS_NewObject(JSContext *cx, const JSClass *clasp, JSObject *proto, JSObject *parent);
 
 /* Queries the [[Extensible]] property of the object. */
 extern JS_PUBLIC_API(bool)
 JS_IsExtensible(JSContext *cx, JS::Handle<JSObject*> obj, bool *extensible);
 
 extern JS_PUBLIC_API(bool)
 JS_IsNative(JSObject *obj);
 
 extern JS_PUBLIC_API(JSRuntime *)
 JS_GetObjectRuntime(JSObject *obj);
 
 /*
  * Unlike JS_NewObject, JS_NewObjectWithGivenProto does not compute a default
  * proto if proto's actual parameter value is null.
  */
 extern JS_PUBLIC_API(JSObject *)
-JS_NewObjectWithGivenProto(JSContext *cx, JSClass *clasp, JSObject *proto,
+JS_NewObjectWithGivenProto(JSContext *cx, const JSClass *clasp, JSObject *proto,
                            JSObject *parent);
 
 /*
  * Freeze obj, and all objects it refers to, recursively. This will not recurse
  * through non-extensible objects, on the assumption that those are already
  * deep-frozen.
  */
 extern JS_PUBLIC_API(bool)
@@ -2587,17 +2587,17 @@ JS_FreezeObject(JSContext *cx, JSObject 
 
 extern JS_PUBLIC_API(bool)
 JS_PreventExtensions(JSContext *cx, JS::Handle<JSObject*> obj);
 
 extern JS_PUBLIC_API(JSObject *)
 JS_New(JSContext *cx, JSObject *ctor, unsigned argc, jsval *argv);
 
 extern JS_PUBLIC_API(JSObject *)
-JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, JSClass *clasp,
+JS_DefineObject(JSContext *cx, JSObject *obj, const char *name, const JSClass *clasp,
                 JSObject *proto, unsigned attrs);
 
 extern JS_PUBLIC_API(bool)
 JS_DefineConstDoubles(JSContext *cx, JSObject *obj, const JSConstDoubleSpec *cds);
 
 extern JS_PUBLIC_API(bool)
 JS_DefineProperties(JSContext *cx, JSObject *obj, const JSPropertySpec *ps);
 
@@ -4240,17 +4240,17 @@ JS_IsConstructing(JSContext *cx, const j
 }
 
 /*
  * A constructor can request that the JS engine create a default new 'this'
  * object of the given class, using the callee to determine parentage and
  * [[Prototype]].
  */
 extern JS_PUBLIC_API(JSObject *)
-JS_NewObjectForConstructor(JSContext *cx, JSClass *clasp, const jsval *vp);
+JS_NewObjectForConstructor(JSContext *cx, const JSClass *clasp, const jsval *vp);
 
 /************************************************************************/
 
 #ifdef JS_GC_ZEAL
 #define JS_DEFAULT_ZEAL_FREQ 100
 
 extern JS_PUBLIC_API(void)
 JS_SetGCZeal(JSContext *cx, uint8_t zeal, uint32_t frequency);
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -762,17 +762,17 @@ js::ObjectMayHaveExtraIndexedProperties(
             return true;
         if (obj->getDenseInitializedLength() > 0)
             return true;
     }
 
     return false;
 }
 
-Class ArrayObject::class_ = {
+const Class ArrayObject::class_ = {
     "Array",
     JSCLASS_HAS_CACHED_PROTO(JSProto_Array),
     array_addProperty,
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/jsbool.cpp
+++ b/js/src/jsbool.cpp
@@ -20,17 +20,17 @@
 #include "vm/ProxyObject.h"
 #include "vm/StringBuffer.h"
 
 #include "vm/BooleanObject-inl.h"
 
 using namespace js;
 using namespace js::types;
 
-Class BooleanObject::class_ = {
+const Class BooleanObject::class_ = {
     "Boolean",
     JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -350,18 +350,18 @@ class ExclusiveContext : public ThreadSa
     JS::Zone *zone() const {
         JS_ASSERT_IF(!compartment(), !zone_);
         JS_ASSERT_IF(compartment(), js::GetCompartmentZone(compartment()) == zone_);
         return zone_;
     }
 
     // Zone local methods that can be used freely from an ExclusiveContext.
     inline bool typeInferenceEnabled() const;
-    types::TypeObject *getNewType(Class *clasp, TaggedProto proto, JSFunction *fun = NULL);
-    types::TypeObject *getLazyType(Class *clasp, TaggedProto proto);
+    types::TypeObject *getNewType(const Class *clasp, TaggedProto proto, JSFunction *fun = NULL);
+    types::TypeObject *getLazyType(const Class *clasp, TaggedProto proto);
     inline js::LifoAlloc &typeLifoAlloc();
 
     // Current global. This is only safe to use within the scope of the
     // AutoCompartment from which it's called.
     inline js::Handle<js::GlobalObject*> global() const;
 
     // Methods to access runtime data that must be protected by locks.
     frontend::ParseMapPool &parseMapPool() {
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -519,17 +519,17 @@ date_convert(JSContext *cx, HandleObject
 
     return DefaultValue(cx, obj, (hint == JSTYPE_VOID) ? JSTYPE_STRING : hint, vp);
 }
 
 /*
  * Other Support routines and definitions
  */
 
-Class DateObject::class_ = {
+const Class DateObject::class_ = {
     js_Date_str,
     JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -49,17 +49,17 @@ exn_trace(JSTracer *trc, JSObject *obj);
 
 static void
 exn_finalize(FreeOp *fop, JSObject *obj);
 
 static bool
 exn_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
             MutableHandleObject objp);
 
-Class ErrorObject::class_ = {
+const Class ErrorObject::class_ = {
     js_Error_str,
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_NEW_RESOLVE |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Error),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -114,27 +114,27 @@ JS_SplicePrototype(JSContext *cx, JSObje
         return JS_SetPrototype(cx, obj, proto);
     }
 
     Rooted<TaggedProto> tagged(cx, TaggedProto(proto));
     return obj->splicePrototype(cx, obj->getClass(), tagged);
 }
 
 JS_FRIEND_API(JSObject *)
-JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *protoArg, JSObject *parentArg)
+JS_NewObjectWithUniqueType(JSContext *cx, const JSClass *clasp, JSObject *protoArg, JSObject *parentArg)
 {
     RootedObject proto(cx, protoArg);
     RootedObject parent(cx, parentArg);
     /*
      * Create our object with a null proto and then splice in the correct proto
      * after we setSingletonType, so that we don't pollute the default
      * TypeObject attached to our proto with information about our object, since
      * we're not going to be using that TypeObject anyway.
      */
-    RootedObject obj(cx, NewObjectWithGivenProto(cx, (js::Class *)clasp, NULL, parent, SingletonObject));
+    RootedObject obj(cx, NewObjectWithGivenProto(cx, (const js::Class *)clasp, NULL, parent, SingletonObject));
     if (!obj)
         return NULL;
     if (!JS_SplicePrototype(cx, obj, proto))
         return NULL;
     return obj;
 }
 
 JS_FRIEND_API(void)
@@ -489,17 +489,17 @@ js::NewFunctionByIdWithReserved(JSContex
     RootedAtom atom(cx, JSID_TO_ATOM(id));
     JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags);
     return NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom,
                        JSFunction::ExtendedFinalizeKind);
 }
 
 JS_FRIEND_API(JSObject *)
 js::InitClassWithReserved(JSContext *cx, JSObject *objArg, JSObject *parent_protoArg,
-                          JSClass *clasp, JSNative constructor, unsigned nargs,
+                          const JSClass *clasp, JSNative constructor, unsigned nargs,
                           const JSPropertySpec *ps, const JSFunctionSpec *fs,
                           const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs)
 {
     RootedObject obj(cx, objArg);
     RootedObject parent_proto(cx, parent_protoArg);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, parent_proto);
     return js_InitClass(cx, obj, parent_proto, Valueify(clasp), constructor,
@@ -519,17 +519,17 @@ js::SetFunctionNativeReserved(JSObject *
 {
     JS_ASSERT(fun->as<JSFunction>().isNative());
     fun->as<JSFunction>().setExtendedSlot(which, val);
 }
 
 JS_FRIEND_API(bool)
 js::GetObjectProto(JSContext *cx, JS::Handle<JSObject*> obj, JS::MutableHandle<JSObject*> proto)
 {
-    js::Class *clasp = GetObjectClass(obj);
+    const js::Class *clasp = GetObjectClass(obj);
     if (clasp == js::ObjectProxyClassPtr ||
         clasp == js::OuterWindowProxyClassPtr ||
         clasp == js::FunctionProxyClassPtr)
     {
         return JS_GetPrototype(cx, obj, proto);
     }
 
     proto.set(reinterpret_cast<const shadow::Object*>(obj.get())->type->proto);
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -53,17 +53,17 @@ JS_FindCompilationScope(JSContext *cx, J
 
 extern JS_FRIEND_API(JSFunction *)
 JS_GetObjectFunction(JSObject *obj);
 
 extern JS_FRIEND_API(bool)
 JS_SplicePrototype(JSContext *cx, JSObject *obj, JSObject *proto);
 
 extern JS_FRIEND_API(JSObject *)
-JS_NewObjectWithUniqueType(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);
+JS_NewObjectWithUniqueType(JSContext *cx, const JSClass *clasp, JSObject *proto, JSObject *parent);
 
 extern JS_FRIEND_API(uint32_t)
 JS_ObjectCountDynamicSlots(JS::HandleObject obj);
 
 extern JS_FRIEND_API(size_t)
 JS_SetProtoCalled(JSContext *cx);
 
 extern JS_FRIEND_API(size_t)
@@ -332,22 +332,22 @@ GetAnyCompartmentInZone(JS::Zone *zone);
  * Shadow declarations of JS internal structures, for access by inline access
  * functions below. Do not use these structures in any other way. When adding
  * new fields for access by inline methods, make sure to add static asserts to
  * the original header file to ensure that offsets are consistent.
  */
 namespace shadow {
 
 struct TypeObject {
-    Class       *clasp;
+    const Class *clasp;
     JSObject    *proto;
 };
 
 struct BaseShape {
-    js::Class *clasp;
+    const js::Class *clasp;
     JSObject *parent;
     JSObject *_1;
     JSCompartment *compartment;
 };
 
 class Shape {
 public:
     shadow::BaseShape *base;
@@ -391,25 +391,25 @@ struct Atom {
     size_t lengthAndFlags;
     const jschar *chars;
 };
 
 } /* namespace shadow */
 
 // This is equal to |&JSObject::class_|.  Use it in places where you don't want
 // to #include jsobj.h.
-extern JS_FRIEND_DATA(js::Class* const) ObjectClassPtr;
+extern JS_FRIEND_DATA(const js::Class* const) ObjectClassPtr;
 
-inline js::Class *
+inline const js::Class *
 GetObjectClass(JSObject *obj)
 {
     return reinterpret_cast<const shadow::Object*>(obj)->type->clasp;
 }
 
-inline JSClass *
+inline const JSClass *
 GetObjectJSClass(JSObject *obj)
 {
     return js::Jsvalify(GetObjectClass(obj));
 }
 
 inline bool
 IsInnerObject(JSObject *obj) {
     return !!GetObjectClass(obj)->ext.outerObject;
@@ -482,17 +482,17 @@ NewFunctionWithReserved(JSContext *cx, J
                         JSObject *parent, const char *name);
 
 JS_FRIEND_API(JSFunction *)
 NewFunctionByIdWithReserved(JSContext *cx, JSNative native, unsigned nargs, unsigned flags,
                             JSObject *parent, jsid id);
 
 JS_FRIEND_API(JSObject *)
 InitClassWithReserved(JSContext *cx, JSObject *obj, JSObject *parent_proto,
-                      JSClass *clasp, JSNative constructor, unsigned nargs,
+                      const JSClass *clasp, JSNative constructor, unsigned nargs,
                       const JSPropertySpec *ps, const JSFunctionSpec *fs,
                       const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs);
 
 JS_FRIEND_API(const JS::Value &)
 GetFunctionNativeReserved(JSObject *fun, size_t which);
 
 JS_FRIEND_API(void)
 SetFunctionNativeReserved(JSObject *fun, size_t which, const JS::Value &val);
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -209,17 +209,17 @@ ResolveInterpretedFunctionPrototype(JSCo
     bool isStarGenerator = obj->as<JSFunction>().isStarGenerator();
     JSObject *objProto;
     if (isStarGenerator)
         objProto = obj->global().getOrCreateStarGeneratorObjectPrototype(cx);
     else
         objProto = obj->global().getOrCreateObjectPrototype(cx);
     if (!objProto)
         return NULL;
-    Class *clasp = &JSObject::class_;
+    const Class *clasp = &JSObject::class_;
 
     RootedObject proto(cx, NewObjectWithGivenProto(cx, clasp, objProto, NULL, SingletonObject));
     if (!proto)
         return NULL;
 
     // Per ES5 15.3.5.2 a user-defined function's .prototype property is
     // initially non-configurable, non-enumerable, and writable.
     RootedValue protoVal(cx, ObjectValue(*proto));
@@ -518,17 +518,17 @@ JSFunction::trace(JSTracer *trc)
 }
 
 static void
 fun_trace(JSTracer *trc, JSObject *obj)
 {
     obj->as<JSFunction>().trace(trc);
 }
 
-Class JSFunction::class_ = {
+const Class JSFunction::class_ = {
     js_Function_str,
     JSCLASS_NEW_RESOLVE | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Function),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     fun_enumerate,
@@ -537,17 +537,17 @@ Class JSFunction::class_ = {
     NULL,                    /* finalize    */
     NULL,                    /* checkAccess */
     NULL,                    /* call        */
     fun_hasInstance,
     NULL,                    /* construct   */
     fun_trace
 };
 
-Class* const js::FunctionClassPtr = &JSFunction::class_;
+const Class* const js::FunctionClassPtr = &JSFunction::class_;
 
 /* Find the body of a function (not including braces). */
 static bool
 FindBody(JSContext *cx, HandleFunction fun, StableCharPtr chars, size_t length,
          size_t *bodyStart, size_t *bodyEnd)
 {
     // We don't need principals, since those are only used for error reporting.
     CompileOptions options(cx);
@@ -1794,17 +1794,17 @@ js::IsConstructor(const Value &v)
     if (obj.is<JSFunction>()) {
         JSFunction &fun = obj.as<JSFunction>();
         return fun.isNativeConstructor() || fun.isInterpretedConstructor();
     }
     return obj.getClass()->construct != NULL;
 }
 
 void
-js::ReportIncompatibleMethod(JSContext *cx, CallReceiver call, Class *clasp)
+js::ReportIncompatibleMethod(JSContext *cx, CallReceiver call, const Class *clasp)
 {
     RootedValue thisv(cx, call.thisv());
 
 #ifdef DEBUG
     if (thisv.isObject()) {
         JS_ASSERT(thisv.toObject().getClass() != clasp ||
                   !thisv.toObject().isNative() ||
                   !thisv.toObject().getProto() ||
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -20,17 +20,17 @@ class FunctionExtended;
 typedef JSNative           Native;
 typedef JSParallelNative   ParallelNative;
 typedef JSThreadSafeNative ThreadSafeNative;
 }
 
 class JSFunction : public JSObject
 {
   public:
-    static js::Class class_;
+    static const js::Class class_;
 
     enum Flags {
         INTERPRETED      = 0x0001,  /* function has a JSScript and environment. */
         NATIVE_CTOR      = 0x0002,  /* native that can be called as a constructor */
         EXTENDED         = 0x0004,  /* structure is FunctionExtended */
         IS_FUN_PROTO     = 0x0010,  /* function is Function.prototype for some global object */
         EXPR_CLOSURE     = 0x0020,  /* expression closure: function(x) x*x */
         HAS_GUESSED_ATOM = 0x0040,  /* function had no explicit name, but a
@@ -554,17 +554,17 @@ extern JSObject *
 CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun);
 
 /*
  * Report an error that call.thisv is not compatible with the specified class,
  * assuming that the method (clasp->name).prototype.<name of callee function>
  * is what was called.
  */
 extern void
-ReportIncompatibleMethod(JSContext *cx, CallReceiver call, Class *clasp);
+ReportIncompatibleMethod(JSContext *cx, CallReceiver call, const Class *clasp);
 
 /*
  * Report an error that call.thisv is not an acceptable this for the callee
  * function.
  */
 extern void
 ReportIncompatible(JSContext *cx, CallReceiver call);
 
--- a/js/src/jsgc.h
+++ b/js/src/jsgc.h
@@ -207,17 +207,17 @@ IsBackgroundFinalized(AllocKind kind)
         false,     /* FINALIZE_EXTERNAL_STRING */
         false,     /* FINALIZE_IONCODE */
     };
     JS_STATIC_ASSERT(JS_ARRAY_LENGTH(map) == FINALIZE_LIMIT);
     return map[kind];
 }
 
 static inline bool
-CanBeFinalizedInBackground(gc::AllocKind kind, Class *clasp)
+CanBeFinalizedInBackground(gc::AllocKind kind, const Class *clasp)
 {
     JS_ASSERT(kind <= gc::FINALIZE_OBJECT_LAST);
     /* If the class has no finalizer or a finalizer that is safe to call on
      * a different thread, we change the finalize kind. For example,
      * FINALIZE_OBJECT0 calls the finalizer on the main thread,
      * FINALIZE_OBJECT0_BACKGROUND calls the finalizer on the gcHelperThread.
      * IsBackgroundFinalized is called to prevent recursively incrementing
      * the finalize kind; kind may already be a background finalize kind.
@@ -313,17 +313,17 @@ GetGCKindSlots(AllocKind thingKind)
       case FINALIZE_OBJECT16_BACKGROUND:
         return 16;
       default:
         MOZ_ASSUME_UNREACHABLE("Bad object finalize kind");
     }
 }
 
 static inline size_t
-GetGCKindSlots(AllocKind thingKind, Class *clasp)
+GetGCKindSlots(AllocKind thingKind, const Class *clasp)
 {
     size_t nslots = GetGCKindSlots(thingKind);
 
     /* An object's private data uses the space taken by its last fixed slot. */
     if (clasp->flags & JSCLASS_HAS_PRIVATE) {
         JS_ASSERT(nslots > 0);
         nslots--;
     }
--- a/js/src/jsgcinlines.h
+++ b/js/src/jsgcinlines.h
@@ -47,17 +47,17 @@ ThreadSafeContext::allocator()
 {
     JS_ASSERT_IF(isJSContext(), &asJSContext()->zone()->allocator == allocator_);
     return allocator_;
 }
 
 namespace gc {
 
 static inline AllocKind
-GetGCObjectKind(Class *clasp)
+GetGCObjectKind(const Class *clasp)
 {
     if (clasp == FunctionClassPtr)
         return JSFunction::FinalizeKind;
     uint32_t nslots = JSCLASS_RESERVED_SLOTS(clasp);
     if (clasp->flags & JSCLASS_HAS_PRIVATE)
         nslots++;
     return GetGCObjectKind(nslots);
 }
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -1040,27 +1040,27 @@ HeapTypeSet::knownSubset(JSContext *cx, 
     if (!isSubset(other))
         return false;
 
     addFreeze(cx);
 
     return true;
 }
 
-Class *
+const Class *
 StackTypeSet::getKnownClass()
 {
     if (unknownObject())
         return NULL;
 
-    Class *clasp = NULL;
+    const Class *clasp = NULL;
     unsigned count = getObjectCount();
 
     for (unsigned i = 0; i < count; i++) {
-        Class *nclasp;
+        const Class *nclasp;
         if (JSObject *object = getSingleObject(i))
             nclasp = object->getClass();
         else if (TypeObject *object = getTypeObject(i))
             nclasp = object->clasp;
         else
             continue;
 
         if (clasp && clasp != nclasp)
@@ -1069,32 +1069,32 @@ StackTypeSet::getKnownClass()
     }
 
     return clasp;
 }
 
 int
 StackTypeSet::getTypedArrayType()
 {
-    Class *clasp = getKnownClass();
+    const Class *clasp = getKnownClass();
 
     if (clasp && IsTypedArrayClass(clasp))
         return clasp - &TypedArrayObject::classes[0];
     return ScalarTypeRepresentation::TYPE_MAX;
 }
 
 bool
 StackTypeSet::isDOMClass()
 {
     if (unknownObject())
         return false;
 
     unsigned count = getObjectCount();
     for (unsigned i = 0; i < count; i++) {
-        Class *clasp;
+        const Class *clasp;
         if (JSObject *object = getSingleObject(i))
             clasp = object->getClass();
         else if (TypeObject *object = getTypeObject(i))
             clasp = object->clasp;
         else
             continue;
 
         if (!(clasp->flags & JSCLASS_IS_DOMJSCLASS))
@@ -1110,17 +1110,17 @@ StackTypeSet::maybeCallable()
     if (!maybeObject())
         return false;
 
     if (unknownObject())
         return true;
 
     unsigned count = getObjectCount();
     for (unsigned i = 0; i < count; i++) {
-        Class *clasp;
+        const Class *clasp;
         if (JSObject *object = getSingleObject(i))
             clasp = object->getClass();
         else if (TypeObject *object = getTypeObject(i))
             clasp = object->clasp;
         else
             continue;
 
         if (clasp->isCallable())
@@ -1280,17 +1280,17 @@ TypeZone::init(JSContext *cx)
     {
         return;
     }
 
     inferenceEnabled = true;
 }
 
 TypeObject *
-TypeCompartment::newTypeObject(ExclusiveContext *cx, Class *clasp, Handle<TaggedProto> proto, bool unknown)
+TypeCompartment::newTypeObject(ExclusiveContext *cx, const Class *clasp, Handle<TaggedProto> proto, bool unknown)
 {
     JS_ASSERT_IF(proto.isObject(), cx->isInsideCurrentCompartment(proto.toObject()));
 
     TypeObject *object = gc::NewGCThing<TypeObject, CanGC>(cx, gc::FINALIZE_TYPE_OBJECT,
                                                            sizeof(TypeObject), gc::TenuredHeap);
     if (!object)
         return NULL;
     new(object) TypeObject(clasp, proto, clasp == &JSFunction::class_, unknown);
@@ -1525,23 +1525,23 @@ types::UseNewTypeForInitializer(JSContex
         if (offset >= startOffset && offset < endOffset)
             return GenericObject;
     }
 
     return SingletonObject;
 }
 
 NewObjectKind
-types::UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc, Class *clasp)
+types::UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc, const Class *clasp)
 {
     return UseNewTypeForInitializer(cx, script, pc, JSCLASS_CACHED_PROTO_KEY(clasp));
 }
 
 static inline bool
-ClassCanHaveExtraProperties(Class *clasp)
+ClassCanHaveExtraProperties(const Class *clasp)
 {
     JS_ASSERT(clasp->resolve);
     return clasp->resolve != JS_ResolveStub || clasp->ops.lookupGeneric || clasp->ops.getGeneric;
 }
 
 static inline bool
 PrototypeHasIndexedProperty(JSContext *cx, JSObject *obj)
 {
@@ -1573,17 +1573,17 @@ types::ArrayPrototypeHasIndexedProperty(
         return true;
 
     return PrototypeHasIndexedProperty(cx, proto);
 }
 
 bool
 types::TypeCanHaveExtraIndexedProperties(JSContext *cx, StackTypeSet *types)
 {
-    Class *clasp = types->getKnownClass();
+    const Class *clasp = types->getKnownClass();
 
     // Note: typed arrays have indexed properties not accounted for by type
     // information, though these are all in bounds and will be accounted for
     // by JIT paths.
     if (!clasp || (ClassCanHaveExtraProperties(clasp) && !IsTypedArrayClass(clasp)))
         return true;
 
     if (types->hasObjectFlags(cx, types::OBJECT_FLAG_SPARSE_INDEXES))
@@ -3477,17 +3477,17 @@ JSObject::shouldSplicePrototype(JSContex
      * has had its __proto__ set after creation.
      */
     if (getProto() != NULL)
         return false;
     return !cx->typeInferenceEnabled() || hasSingletonType();
 }
 
 bool
-JSObject::splicePrototype(JSContext *cx, Class *clasp, Handle<TaggedProto> proto)
+JSObject::splicePrototype(JSContext *cx, const Class *clasp, Handle<TaggedProto> proto)
 {
     JS_ASSERT(cx->compartment() == compartment());
 
     RootedObject self(cx, this);
 
     /*
      * For singleton types representing only a single JSObject, the proto
      * can be rearranged as needed without destroying type information for
@@ -3606,41 +3606,41 @@ JSObject::makeLazyType(JSContext *cx, Ha
 
     return type;
 }
 
 /* static */ inline HashNumber
 TypeObjectEntry::hash(const Lookup &lookup)
 {
     return PointerHasher<JSObject *, 3>::hash(lookup.proto.raw()) ^
-           PointerHasher<Class *, 3>::hash(lookup.clasp);
+           PointerHasher<const Class *, 3>::hash(lookup.clasp);
 }
 
 /* static */ inline bool
 TypeObjectEntry::match(TypeObject *key, const Lookup &lookup)
 {
     return key->proto == lookup.proto.raw() && key->clasp == lookup.clasp;
 }
 
 #ifdef DEBUG
 bool
-JSObject::hasNewType(Class *clasp, TypeObject *type)
+JSObject::hasNewType(const Class *clasp, TypeObject *type)
 {
     TypeObjectSet &table = compartment()->newTypeObjects;
 
     if (!table.initialized())
         return false;
 
     TypeObjectSet::Ptr p = table.lookup(TypeObjectSet::Lookup(clasp, this));
     return p && *p == type;
 }
 #endif /* DEBUG */
 
 /* static */ bool
-JSObject::setNewTypeUnknown(JSContext *cx, Class *clasp, HandleObject obj)
+JSObject::setNewTypeUnknown(JSContext *cx, const Class *clasp, HandleObject obj)
 {
     if (!obj->setFlag(cx, js::BaseShape::NEW_TYPE_UNKNOWN))
         return false;
 
     /*
      * If the object already has a new type, mark that type as unknown. It will
      * not have the SETS_MARKED_UNKNOWN bit set, so may require a type set
      * crawl if prototypes of the object change dynamically in the future.
@@ -3650,17 +3650,17 @@ JSObject::setNewTypeUnknown(JSContext *c
         if (TypeObjectSet::Ptr p = table.lookup(TypeObjectSet::Lookup(clasp, obj.get())))
             MarkTypeObjectUnknownProperties(cx, *p);
     }
 
     return true;
 }
 
 TypeObject *
-ExclusiveContext::getNewType(Class *clasp, TaggedProto proto_, JSFunction *fun_)
+ExclusiveContext::getNewType(const Class *clasp, TaggedProto proto_, JSFunction *fun_)
 {
     JS_ASSERT_IF(fun_, proto_.isObject());
     JS_ASSERT_IF(proto_.isObject(), isInsideCurrentCompartment(proto_.toObject()));
 
     TypeObjectSet &newTypeObjects = compartment_->newTypeObjects;
 
     if (!newTypeObjects.initialized() && !newTypeObjects.init())
         return NULL;
@@ -3753,17 +3753,17 @@ ExclusiveContext::getNewType(Class *clas
      */
     if (type->unknownProperties())
         type->flags |= OBJECT_FLAG_SETS_MARKED_UNKNOWN;
 
     return type;
 }
 
 TypeObject *
-ExclusiveContext::getLazyType(Class *clasp, TaggedProto proto)
+ExclusiveContext::getLazyType(const Class *clasp, TaggedProto proto)
 {
     JS_ASSERT_IF(proto.isObject(), compartment() == proto.toObject()->compartment());
 
     AutoEnterAnalysis enter(this);
 
     TypeObjectSet &table = compartment()->lazyTypeObjects;
 
     if (!table.initialized() && !table.init())
--- a/js/src/jsinfer.h
+++ b/js/src/jsinfer.h
@@ -609,17 +609,17 @@ class StackTypeSet : public TypeSet
 
         return hasAnyFlag(TYPE_FLAG_ANYOBJECT) || baseObjectCount() > 0;
     }
 
     /* Whether the type set contains objects with any of a set of flags. */
     bool hasObjectFlags(JSContext *cx, TypeObjectFlags flags);
 
     /* Get the class shared by all objects in this set, or NULL. */
-    Class *getKnownClass();
+    const Class *getKnownClass();
 
     /* Get the prototype shared by all objects in this set, or NULL. */
     JSObject *getCommonPrototype();
 
     /* Get the typed array type of all objects in this set, or TypedArrayObject::TYPE_MAX. */
     int getTypedArrayType();
 
     /* Whether all objects have JSCLASS_IS_DOMJSCLASS set. */
@@ -976,17 +976,17 @@ struct TypeTypedObject : public TypeObje
  * type object itself, the type object is also destroyed, and the JS object
  * reverts to having a lazy type.
  */
 
 /* Type information about an object accessed by a script. */
 struct TypeObject : gc::Cell
 {
     /* Class shared by objects using this type. */
-    Class *clasp;
+    const Class *clasp;
 
     /* Prototype shared by objects using this type. */
     HeapPtrObject proto;
 
     /*
      * Whether there is a singleton JS object with this type. That JS object
      * must appear in type sets instead of this; we include the back reference
      * here to allow reverting the JS object to a lazy type.
@@ -1076,17 +1076,17 @@ struct TypeObject : gc::Cell
 
     /* If this is an interpreted function, the function object. */
     HeapPtrFunction interpretedFunction;
 
 #if JS_BITS_PER_WORD == 32
     uint32_t padding;
 #endif
 
-    inline TypeObject(Class *clasp, TaggedProto proto, bool isFunction, bool unknown);
+    inline TypeObject(const Class *clasp, TaggedProto proto, bool isFunction, bool unknown);
 
     bool isFunction() { return !!(flags & OBJECT_FLAG_FUNCTION); }
 
     bool hasAnyFlags(TypeObjectFlags flags) {
         JS_ASSERT((flags & OBJECT_FLAG_DYNAMIC_MASK) == flags);
         return !!(this->flags & flags);
     }
     bool hasAllFlags(TypeObjectFlags flags) {
@@ -1199,20 +1199,20 @@ struct TypeObject : gc::Cell
 
 /*
  * Entries for the per-compartment set of type objects which are the default
  * 'new' or the lazy types of some prototype.
  */
 struct TypeObjectEntry : DefaultHasher<ReadBarriered<TypeObject> >
 {
     struct Lookup {
-        Class *clasp;
+        const Class *clasp;
         TaggedProto proto;
 
-        Lookup(Class *clasp, TaggedProto proto) : clasp(clasp), proto(proto) {}
+        Lookup(const Class *clasp, TaggedProto proto) : clasp(clasp), proto(proto) {}
     };
 
     static inline HashNumber hash(const Lookup &lookup);
     static inline bool match(TypeObject *key, const Lookup &lookup);
 };
 typedef HashSet<ReadBarriered<TypeObject>, TypeObjectEntry, SystemAllocPolicy> TypeObjectSet;
 
 /* Whether to use a new type object when calling 'new' at script/pc. */
@@ -1492,17 +1492,17 @@ struct TypeCompartment
     void print(JSContext *cx, bool force);
 
     /*
      * Make a function or non-function object associated with an optional
      * script. The 'key' parameter here may be an array, typed array, function
      * or JSProto_Object to indicate a type whose class is unknown (not just
      * js_ObjectClass).
      */
-    TypeObject *newTypeObject(ExclusiveContext *cx, Class *clasp, Handle<TaggedProto> proto,
+    TypeObject *newTypeObject(ExclusiveContext *cx, const Class *clasp, Handle<TaggedProto> proto,
                               bool unknown = false);
 
     /* Get or make an object for an allocation site, and add to the allocation site table. */
     TypeObject *addAllocationSiteTypeObject(JSContext *cx, AllocationSiteKey key);
 
     void processPendingRecompiles(FreeOp *fop);
 
     /* Mark all types as needing destruction once inference has 'finished'. */
--- a/js/src/jsinferinlines.h
+++ b/js/src/jsinferinlines.h
@@ -424,17 +424,17 @@ struct AutoEnterCompilation
 
 /*
  * These functions check whether inference is enabled before performing some
  * action on the type state. To avoid checking cx->typeInferenceEnabled()
  * everywhere, it is generally preferred to use one of these functions or
  * a type function on JSScript to perform inference operations.
  */
 
-inline Class *
+inline const Class *
 GetClassForProtoKey(JSProtoKey key)
 {
     switch (key) {
       case JSProto_Object:
         return &JSObject::class_;
       case JSProto_Array:
         return &ArrayObject::class_;
 
@@ -783,17 +783,17 @@ struct AllocationSiteKey : public Defaul
     }
 };
 
 /* Whether to use a new type object for an initializer opcode at script/pc. */
 js::NewObjectKind
 UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc, JSProtoKey key);
 
 js::NewObjectKind
-UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc, Class *clasp);
+UseNewTypeForInitializer(JSContext *cx, JSScript *script, jsbytecode *pc, const Class *clasp);
 
 /* static */ inline TypeObject *
 TypeScript::InitObject(JSContext *cx, JSScript *script, jsbytecode *pc, JSProtoKey kind)
 {
     JS_ASSERT(!UseNewTypeForInitializer(cx, script, pc, kind));
 
     /* :XXX: Limit script->length so we don't need to check the offset up front? */
     uint32_t offset = pc - script->code;
@@ -1444,17 +1444,17 @@ TypeCallsite::TypeCallsite(JSContext *cx
     /* Caller must check for failure. */
     argumentTypes = cx->analysisLifoAlloc().newArray<StackTypeSet*>(argumentCount);
 }
 
 /////////////////////////////////////////////////////////////////////
 // TypeObject
 /////////////////////////////////////////////////////////////////////
 
-inline TypeObject::TypeObject(Class *clasp, TaggedProto proto, bool function, bool unknown)
+inline TypeObject::TypeObject(const Class *clasp, TaggedProto proto, bool function, bool unknown)
 {
     mozilla::PodZero(this);
 
     /* Inner objects may not appear on prototype chains. */
     JS_ASSERT_IF(proto.isObject(), !proto.toObject()->getClass()->ext.outerObject);
 
     this->clasp = clasp;
     this->proto = proto.raw();
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -191,17 +191,17 @@ Snapshot(JSContext *cx, JSObject *pobj_,
 {
     IdSet ht(cx);
     if (!ht.init(32))
         return false;
 
     RootedObject pobj(cx, pobj_);
 
     do {
-        Class *clasp = pobj->getClass();
+        const Class *clasp = pobj->getClass();
         if (pobj->isNative() &&
             !pobj->getOps()->enumerate &&
             !(clasp->flags & JSCLASS_NEW_ENUMERATE)) {
             if (!clasp->enumerate(cx, pobj))
                 return false;
             if (!EnumerateNativeProperties(cx, pobj, flags, ht, props))
                 return false;
         } else {
@@ -377,17 +377,17 @@ NewPropertyIteratorObject(JSContext *cx,
         RootedTypeObject type(cx, cx->getNewType(&PropertyIteratorObject::class_, NULL));
         if (!type)
             return NULL;
 
         JSObject *metadata = NULL;
         if (!NewObjectMetadata(cx, &metadata))
             return NULL;
 
-        Class *clasp = &PropertyIteratorObject::class_;
+        const Class *clasp = &PropertyIteratorObject::class_;
         RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, NULL, NULL, metadata,
                                                           ITERATOR_FINALIZE_KIND));
         if (!shape)
             return NULL;
 
         JSObject *obj = JSObject::create(cx, ITERATOR_FINALIZE_KIND,
                                          GetInitialHeap(GenericObject, clasp), shape, type);
         if (!obj)
@@ -827,17 +827,17 @@ PropertyIteratorObject::trace(JSTracer *
 
 void
 PropertyIteratorObject::finalize(FreeOp *fop, JSObject *obj)
 {
     if (NativeIterator *ni = obj->as<PropertyIteratorObject>().getNativeIterator())
         fop->free_(ni);
 }
 
-Class PropertyIteratorObject::class_ = {
+const Class PropertyIteratorObject::class_ = {
     "Iterator",
     JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Iterator) |
     JSCLASS_HAS_PRIVATE |
     JSCLASS_BACKGROUND_FINALIZE,
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
@@ -932,17 +932,17 @@ ElementIteratorObject::next_impl(JSConte
   close:
     // Close the iterator. The TargetSlot will never be used again, so don't keep a
     // reference to it.
     iterobj->setReservedSlot(TargetSlot, UndefinedValue());
     iterobj->setReservedSlot(IndexSlot, Int32Value(int32_t(CLOSED_INDEX)));
     return false;
 }
 
-Class ElementIteratorObject::class_ = {
+const Class ElementIteratorObject::class_ = {
     "Array Iterator",
     JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(ElementIteratorObject::NumSlots),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
@@ -1295,17 +1295,17 @@ js_IteratorNext(JSContext *cx, HandleObj
 
 static bool
 stopiter_hasInstance(JSContext *cx, HandleObject obj, MutableHandleValue v, bool *bp)
 {
     *bp = IsStopIteration(v);
     return true;
 }
 
-Class StopIterationObject::class_ = {
+const Class StopIterationObject::class_ = {
     "StopIteration",
     JSCLASS_HAS_CACHED_PROTO(JSProto_StopIteration) |
     JSCLASS_FREEZE_PROTO,
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
@@ -1448,17 +1448,17 @@ GeneratorState::pushInterpreterFrame(JSC
 
     gen_->fp->clearSuspended();
 
     cx->enterGenerator(gen_);   /* OOM check above. */
     entered_ = true;
     return gen_->fp;
 }
 
-Class LegacyGeneratorObject::class_ = {
+const Class LegacyGeneratorObject::class_ = {
     "Generator",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS,
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
@@ -1471,17 +1471,17 @@ Class LegacyGeneratorObject::class_ = {
     TraceGenerator<LegacyGeneratorObject>,
     {
         NULL,                /* outerObject    */
         NULL,                /* innerObject    */
         iterator_iteratorObject,
     }
 };
 
-Class StarGeneratorObject::class_ = {
+const Class StarGeneratorObject::class_ = {
     "Generator",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS,
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
@@ -1869,17 +1869,17 @@ GlobalObject::initIteratorClasses(JSCont
         if (!DefinePropertiesAndBrand(cx, iteratorProto, NULL, iterator_methods))
             return false;
         if (!DefineConstructorAndPrototype(cx, global, JSProto_Iterator, ctor, iteratorProto))
             return false;
     }
 
     RootedObject proto(cx);
     if (global->getSlot(ELEMENT_ITERATOR_PROTO).isUndefined()) {
-        Class *cls = &ElementIteratorObject::class_;
+        const Class *cls = &ElementIteratorObject::class_;
         proto = global->createBlankPrototypeInheriting(cx, cls, *iteratorProto);
         if (!proto || !DefinePropertiesAndBrand(cx, proto, NULL, ElementIteratorObject::methods))
             return false;
         global->setReservedSlot(ELEMENT_ITERATOR_PROTO, ObjectValue(*proto));
     }
 
     if (global->getSlot(LEGACY_GENERATOR_OBJECT_PROTO).isUndefined()) {
         proto = NewObjectWithObjectPrototype(cx, global);
--- a/js/src/jsiter.h
+++ b/js/src/jsiter.h
@@ -112,17 +112,17 @@ struct NativeIterator
     static void destroy(NativeIterator *iter) {
         js_free(iter);
     }
 };
 
 class PropertyIteratorObject : public JSObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 
     NativeIterator *getNativeIterator() const {
         return static_cast<js::NativeIterator *>(getPrivate());
     }
     void setNativeIterator(js::NativeIterator *ni) {
         setPrivate(ni);
     }
 
@@ -142,17 +142,17 @@ class PropertyIteratorObject : public JS
  *   }
  *
  * However they are not generators. They are a different class. The semantics
  * of Array iterators will be given in the eventual ES6 spec in full detail.
  */
 class ElementIteratorObject : public JSObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 
     static JSObject *create(JSContext *cx, Handle<Value> target);
     static const JSFunctionSpec methods[];
 
     enum {
         TargetSlot,
         IndexSlot,
         NumSlots
--- a/js/src/jsmath.cpp
+++ b/js/src/jsmath.cpp
@@ -96,17 +96,17 @@ MathCache::MathCache() {
 }
 
 size_t
 MathCache::sizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf)
 {
     return mallocSizeOf(this);
 }
 
-Class js::MathClass = {
+const Class js::MathClass = {
     js_Math_str,
     JSCLASS_HAS_CACHED_PROTO(JSProto_Math),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -441,17 +441,17 @@ js::num_parseInt(JSContext *cx, unsigned
 static const JSFunctionSpec number_functions[] = {
     JS_FN(js_isNaN_str,         num_isNaN,           1,0),
     JS_FN(js_isFinite_str,      num_isFinite,        1,0),
     JS_FN(js_parseFloat_str,    num_parseFloat,      1,0),
     JS_FN(js_parseInt_str,      num_parseInt,        2,0),
     JS_FS_END
 };
 
-Class NumberObject::class_ = {
+const Class NumberObject::class_ = {
     js_Number_str,
     JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Number),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -65,29 +65,29 @@ using namespace js::types;
 
 using js::frontend::IsIdentifier;
 using mozilla::ArrayLength;
 using mozilla::DebugOnly;
 using mozilla::RoundUpPow2;
 
 JS_STATIC_ASSERT(int32_t((JSObject::NELEMENTS_LIMIT - 1) * sizeof(Value)) == int64_t((JSObject::NELEMENTS_LIMIT - 1) * sizeof(Value)));
 
-Class JSObject::class_ = {
+const Class JSObject::class_ = {
     js_Object_str,
     JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub
 };
 
-Class* const js::ObjectClassPtr = &JSObject::class_;
+const Class* const js::ObjectClassPtr = &JSObject::class_;
 
 JS_FRIEND_API(JSObject *)
 JS_ObjectToInnerObject(JSContext *cx, JSObject *objArg)
 {
     RootedObject obj(cx, objArg);
     if (!obj) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_INACTIVE);
         return NULL;
@@ -1241,27 +1241,27 @@ JSObject::className(JSContext *cx, Handl
     return obj->getClass()->name;
 }
 
 /*
  * Get the GC kind to use for scripted 'new' on the given class.
  * FIXME bug 547327: estimate the size from the allocation site.
  */
 static inline gc::AllocKind
-NewObjectGCKind(js::Class *clasp)
+NewObjectGCKind(const js::Class *clasp)
 {
     if (clasp == &ArrayObject::class_)
         return gc::FINALIZE_OBJECT8;
     if (clasp == &JSFunction::class_)
         return gc::FINALIZE_OBJECT2;
     return gc::FINALIZE_OBJECT4;
 }
 
 static inline JSObject *
-NewObject(ExclusiveContext *cx, Class *clasp, types::TypeObject *type_, JSObject *parent,
+NewObject(ExclusiveContext *cx, const Class *clasp, types::TypeObject *type_, JSObject *parent,
           gc::AllocKind kind, NewObjectKind newKind)
 {
     JS_ASSERT(clasp != &ArrayObject::class_);
     JS_ASSERT_IF(clasp == &JSFunction::class_,
                  kind == JSFunction::FinalizeKind || kind == JSFunction::ExtendedFinalizeKind);
     JS_ASSERT_IF(parent, &parent->global() == cx->global());
 
     RootedTypeObject type(cx, type_);
@@ -1297,26 +1297,26 @@ NewObject(ExclusiveContext *cx, Class *c
         cx->asJSContext()->runtime()->gcIncrementalEnabled = false;
     }
 
     Probes::createObject(cx, obj);
     return obj;
 }
 
 void
-NewObjectCache::fillProto(EntryIndex entry, Class *clasp, js::TaggedProto proto,
+NewObjectCache::fillProto(EntryIndex entry, const Class *clasp, js::TaggedProto proto,
                           gc::AllocKind kind, JSObject *obj)
 {
     JS_ASSERT_IF(proto.isObject(), !proto.toObject()->is<GlobalObject>());
     JS_ASSERT(obj->getTaggedProto() == proto);
     return fill(entry, clasp, proto.raw(), kind, obj);
 }
 
 JSObject *
-js::NewObjectWithGivenProto(ExclusiveContext *cxArg, js::Class *clasp,
+js::NewObjectWithGivenProto(ExclusiveContext *cxArg, const js::Class *clasp,
                             js::TaggedProto proto_, JSObject *parent_,
                             gc::AllocKind allocKind, NewObjectKind newKind)
 {
     Rooted<TaggedProto> proto(cxArg, proto_);
     RootedObject parent(cxArg, parent_);
 
     if (CanBeFinalizedInBackground(allocKind, clasp))
         allocKind = GetBackgroundAllocKind(allocKind);
@@ -1358,17 +1358,17 @@ js::NewObjectWithGivenProto(ExclusiveCon
                                                                   proto, allocKind, obj);
     }
 
     return obj;
 }
 
 JSObject *
 js::NewObjectWithClassProtoCommon(ExclusiveContext *cxArg,
-                                  js::Class *clasp, JSObject *protoArg, JSObject *parentArg,
+                                  const js::Class *clasp, JSObject *protoArg, JSObject *parentArg,
                                   gc::AllocKind allocKind, NewObjectKind newKind)
 {
     if (protoArg)
         return NewObjectWithGivenProto(cxArg, clasp, protoArg, parentArg, allocKind, newKind);
 
     if (CanBeFinalizedInBackground(allocKind, clasp))
         allocKind = GetBackgroundAllocKind(allocKind);
 
@@ -1523,17 +1523,17 @@ js::NewReshapedObject(JSContext *cx, Han
         }
     }
     JS_ASSERT(!res->inDictionaryMode());
 
     return res;
 }
 
 JSObject*
-js::CreateThis(JSContext *cx, Class *newclasp, HandleObject callee)
+js::CreateThis(JSContext *cx, const Class *newclasp, HandleObject callee)
 {
     RootedValue protov(cx);
     if (!JSObject::getProperty(cx, callee, callee, cx->names().classPrototype, &protov))
         return NULL;
 
     JSObject *proto = protov.isObjectOrNull() ? protov.toObjectOrNull() : NULL;
     JSObject *parent = callee->getParent();
     gc::AllocKind kind = NewObjectGCKind(newclasp);
@@ -1894,18 +1894,18 @@ JSObject::ReserveForTradeGuts(JSContext 
      * numbers of fixed slots, we reserve all space ahead of time so that the
      * swaps can be performed infallibly.
      */
 
     /*
      * Swap prototypes and classes on the two objects, so that TradeGuts can
      * preserve the types of the two objects.
      */
-    Class *aClass = a->getClass();
-    Class *bClass = b->getClass();
+    const Class *aClass = a->getClass();
+    const Class *bClass = b->getClass();
     Rooted<TaggedProto> aProto(cx, a->getTaggedProto());
     Rooted<TaggedProto> bProto(cx, b->getTaggedProto());
     if (!SetClassAndProto(cx, a, bClass, bProto, false))
         return false;
     if (!SetClassAndProto(cx, b, aClass, aProto, false))
         return false;
 
     if (a->tenuredSizeOfThis() == b->tenuredSizeOfThis())
@@ -2209,17 +2209,17 @@ ClearClassObject(JSObject *obj, JSProtoK
         return;
 
     obj->setSlot(key, UndefinedValue());
     obj->setSlot(JSProto_LIMIT + key, UndefinedValue());
 }
 
 JSObject *
 js::DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, HandleAtom atom,
-                                  JSObject *protoProto, Class *clasp,
+                                  JSObject *protoProto, const Class *clasp,
                                   Native constructor, unsigned nargs,
                                   const JSPropertySpec *ps, const JSFunctionSpec *fs,
                                   const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs,
                                   JSObject **ctorp, AllocKind ctorKind)
 {
     /*
      * Create a prototype object for this class.
      *
@@ -2354,40 +2354,40 @@ bad:
  * Otherwise, when we delete them, we might accidentally recreate them via a
  * lazy initialization. We use the presence of a ctor or proto in the
  * global object's slot to indicate that they've been constructed, but this only
  * works for classes which have a proto and ctor. Classes which don't have one
  * can call MarkStandardClassInitializedNoProto(), and we can always check
  * whether a class is initialized by calling IsStandardClassResolved().
  */
 bool
-js::IsStandardClassResolved(JSObject *obj, js::Class *clasp)
+js::IsStandardClassResolved(JSObject *obj, const js::Class *clasp)
 {
     JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp);
 
     /* If the constructor is undefined, then it hasn't been initialized. */
     return (obj->getReservedSlot(key) != UndefinedValue());
 }
 
 void
-js::MarkStandardClassInitializedNoProto(JSObject *obj, js::Class *clasp)
+js::MarkStandardClassInitializedNoProto(JSObject *obj, const js::Class *clasp)
 {
     JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp);
 
     /*
      * We use True so that it's obvious what we're doing (instead of, say,
      * Null, which might be miscontrued as an error in setting Undefined).
      */
     if (obj->getReservedSlot(key) == UndefinedValue())
         obj->setSlot(key, BooleanValue(true));
 }
 
 JSObject *
 js_InitClass(JSContext *cx, HandleObject obj, JSObject *protoProto_,
-             Class *clasp, Native constructor, unsigned nargs,
+             const Class *clasp, Native constructor, unsigned nargs,
              const JSPropertySpec *ps, const JSFunctionSpec *fs,
              const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs,
              JSObject **ctorp, AllocKind ctorKind)
 {
     RootedObject protoProto(cx, protoProto_);
 
     /* Assert mandatory function pointer members. */
     JS_ASSERT(clasp->addProperty);
@@ -2933,25 +2933,25 @@ js_InitNullClass(JSContext *cx, HandleOb
     return NULL;
 }
 
 #define DECLARE_PROTOTYPE_CLASS_INIT(name,code,init) \
     extern JSObject *init(JSContext *cx, Handle<JSObject*> obj);
 JS_FOR_EACH_PROTOTYPE(DECLARE_PROTOTYPE_CLASS_INIT)
 #undef DECLARE_PROTOTYPE_CLASS_INIT
 
-static ClassInitializerOp lazy_prototype_init[JSProto_LIMIT] = {
+static const ClassInitializerOp lazy_prototype_init[JSProto_LIMIT] = {
 #define LAZY_PROTOTYPE_INIT(name,code,init) init,
     JS_FOR_EACH_PROTOTYPE(LAZY_PROTOTYPE_INIT)
 #undef LAZY_PROTOTYPE_INIT
 };
 
 bool
 js::SetClassAndProto(JSContext *cx, HandleObject obj,
-                     Class *clasp, Handle<js::TaggedProto> proto, bool checkForCycles)
+                     const Class *clasp, Handle<js::TaggedProto> proto, bool checkForCycles)
 {
     JS_ASSERT_IF(!checkForCycles, obj.get() != proto.raw());
 
     /*
      * Regenerate shapes for all of the scopes along the old prototype chain,
      * in case any entries were filled by looking up through obj. Stop when a
      * non-native object is found, prototype lookups will not be cached across
      * these.
@@ -3093,17 +3093,17 @@ js_IdentifyClassPrototype(JSObject *obj)
     if (v.isObject() && obj == &v.toObject())
         return key;
 
     // False alarm - just an instance.
     return JSProto_Null;
 }
 
 bool
-js_FindClassObject(ExclusiveContext *cx, JSProtoKey protoKey, MutableHandleValue vp, Class *clasp)
+js_FindClassObject(ExclusiveContext *cx, JSProtoKey protoKey, MutableHandleValue vp, const Class *clasp)
 {
     RootedId id(cx);
 
     if (protoKey != JSProto_Null) {
         JS_ASSERT(JSProto_Null < protoKey);
         JS_ASSERT(protoKey < JSProto_LIMIT);
         RootedObject cobj(cx);
         if (!js_GetClassObject(cx, cx->global(), protoKey, &cobj))
@@ -3391,17 +3391,17 @@ JSObject::addDataProperty(ExclusiveConte
 
 /*
  * Backward compatibility requires allowing addProperty hooks to mutate the
  * nominal initial value of a slotful property, while GC safety wants that
  * value to be stored before the call-out through the hook.  Optimize to do
  * both while saving cycles for classes that stub their addProperty hook.
  */
 static inline bool
-CallAddPropertyHook(ExclusiveContext *cx, Class *clasp, HandleObject obj, HandleShape shape,
+CallAddPropertyHook(ExclusiveContext *cx, const Class *clasp, HandleObject obj, HandleShape shape,
                     HandleValue nominal)
 {
     if (clasp->addProperty != JS_PropertyStub) {
         if (!cx->shouldBeJSContext())
             return false;
 
         /* Make a local copy of value so addProperty can mutate its inout parameter. */
         RootedValue value(cx, nominal);
@@ -3415,17 +3415,17 @@ CallAddPropertyHook(ExclusiveContext *cx
             if (shape->hasSlot())
                 JSObject::nativeSetSlotWithType(cx, obj, shape, value);
         }
     }
     return true;
 }
 
 static inline bool
-CallAddPropertyHookDense(ExclusiveContext *cx, Class *clasp, HandleObject obj, uint32_t index,
+CallAddPropertyHookDense(ExclusiveContext *cx, const Class *clasp, HandleObject obj, uint32_t index,
                          HandleValue nominal)
 {
     /* Inline addProperty for array objects. */
     if (obj->is<ArrayObject>()) {
         Rooted<ArrayObject*> arr(cx, &obj->as<ArrayObject>());
         uint32_t length = arr->length();
         if (index >= length)
             ArrayObject::setLength(cx, arr, index + 1);
@@ -3596,17 +3596,17 @@ js::DefineNativeProperty(ExclusiveContex
      * is not possible.
      */
     if (!(defineHow & DNP_DONT_PURGE)) {
         if (!PurgeScopeChain(cx, obj, id))
             return false;
     }
 
     /* Use the object's class getter and setter by default. */
-    Class *clasp = obj->getClass();
+    const Class *clasp = obj->getClass();
     if (!getter && !(attrs & JSPROP_GETTER))
         getter = clasp->getProperty;
     if (!setter && !(attrs & JSPROP_SETTER))
         setter = clasp->setProperty;
 
     if ((getter == JS_PropertyStub) && !(defineHow & DNP_SKIP_TYPE)) {
         /*
          * Type information for normal native properties should reflect the
@@ -3647,17 +3647,17 @@ js::DefineNativeProperty(ExclusiveContex
  *
  *   - Otherwise no property was resolved. Set *propp = NULL and *recursedp = false
  *     and return true.
  */
 static JS_ALWAYS_INLINE bool
 CallResolveOp(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
               MutableHandleObject objp, MutableHandleShape propp, bool *recursedp)
 {
-    Class *clasp = obj->getClass();
+    const Class *clasp = obj->getClass();
     JSResolveOp resolve = clasp->resolve;
 
     /*
      * Avoid recursion on (obj, id) already being resolved on cx.
      *
      * Once we have successfully added an entry for (obj, key) to
      * cx->resolvingTable, control must go through cleanup: before
      * returning.  But note that JS_DHASH_ADD may find an existing
@@ -4608,17 +4608,17 @@ baseops::SetPropertyHelper(JSContext *cx
 
     /*
      * Now either shape is null, meaning id was not found in obj or one of its
      * prototypes; or shape is non-null, meaning id was found directly in pobj.
      */
     unsigned attrs = JSPROP_ENUMERATE;
     unsigned flags = 0;
     int shortid = 0;
-    Class *clasp = obj->getClass();
+    const Class *clasp = obj->getClass();
     PropertyOp getter = clasp->getProperty;
     StrictPropertyOp setter = clasp->setProperty;
 
     if (IsImplicitDenseElement(shape)) {
         /* ES5 8.12.4 [[Put]] step 2, for a dense data property on pobj. */
         if (pobj != obj)
             shape = NULL;
     } else if (shape) {
@@ -4886,17 +4886,17 @@ MaybeCallMethod(JSContext *cx, HandleObj
 
 JS_FRIEND_API(bool)
 js::DefaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp)
 {
     JS_ASSERT(hint == JSTYPE_NUMBER || hint == JSTYPE_STRING || hint == JSTYPE_VOID);
 
     Rooted<jsid> id(cx);
 
-    Class *clasp = obj->getClass();
+    const Class *clasp = obj->getClass();
     if (hint == JSTYPE_STRING) {
         id = NameToId(cx->names().toString);
 
         /* Optimize (new String(...)).toString(). */
         if (clasp == &StringObject::class_) {
             if (ClassMethodIsNative(cx, obj, &StringObject::class_, id, js_str_toString)) {
                 vp.setString(obj->as<StringObject>().unbox());
                 return true;
@@ -4962,17 +4962,17 @@ js::DefaultValue(JSContext *cx, HandleOb
     return false;
 }
 
 JS_FRIEND_API(bool)
 JS_EnumerateState(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
                   MutableHandleValue statep, JS::MutableHandleId idp)
 {
     /* If the class has a custom JSCLASS_NEW_ENUMERATE hook, call it. */
-    Class *clasp = obj->getClass();
+    const Class *clasp = obj->getClass();
     JSEnumerateOp enumerate = clasp->enumerate;
     if (clasp->flags & JSCLASS_NEW_ENUMERATE) {
         JS_ASSERT(enumerate != JS_EnumerateStub);
         return ((JSNewEnumerateOp) enumerate)(cx, obj, enum_op, statep, idp);
     }
 
     if (!enumerate(cx, obj))
         return false;
@@ -5098,17 +5098,17 @@ js::GetClassPrototypePure(GlobalObject *
 }
 
 /*
  * The first part of this function has been hand-expanded and optimized into
  * NewBuiltinClassInstance in jsobjinlines.h.
  */
 bool
 js_GetClassPrototype(ExclusiveContext *cx, JSProtoKey protoKey,
-                     MutableHandleObject protop, Class *clasp)
+                     MutableHandleObject protop, const Class *clasp)
 {
     if (JSObject *proto = GetClassPrototypePure(cx->global(), protoKey)) {
         protop.set(proto);
         return true;
     }
 
     RootedValue v(cx);
     if (!js_FindClassObject(cx, protoKey, &v, clasp))
@@ -5292,17 +5292,17 @@ dumpValue(const Value &v)
         if (fun->hasScript()) {
             JSScript *script = fun->nonLazyScript();
             fprintf(stderr, " (%s:%u)",
                     script->filename() ? script->filename() : "", script->lineno);
         }
         fprintf(stderr, " at %p>", (void *) fun);
     } else if (v.isObject()) {
         JSObject *obj = &v.toObject();
-        Class *clasp = obj->getClass();
+        const Class *clasp = obj->getClass();
         fprintf(stderr, "<%s%s at %p>",
                 clasp->name,
                 (clasp == &JSObject::class_) ? "" : " object",
                 (void *) obj);
     } else if (v.isBoolean()) {
         if (v.toBoolean())
             fprintf(stderr, "true");
         else
@@ -5385,18 +5385,18 @@ JSObject::uninlinedIsProxy() const
     return is<ProxyObject>();
 }
 
 void
 JSObject::dump()
 {
     JSObject *obj = this;
     fprintf(stderr, "object %p\n", (void *) obj);
-    Class *clasp = obj->getClass();
-    fprintf(stderr, "class %p %s\n", (void *)clasp, clasp->name);
+    const Class *clasp = obj->getClass();
+    fprintf(stderr, "class %p %s\n", (const void *)clasp, clasp->name);
 
     fprintf(stderr, "flags:");
     if (obj->isDelegate()) fprintf(stderr, " delegate");
     if (!obj->is<ProxyObject>() && !obj->nonProxyIsExtensible()) fprintf(stderr, " not_extensible");
     if (obj->isIndexed()) fprintf(stderr, " indexed");
 
     if (obj->isNative()) {
         if (obj->inDictionaryMode())
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -147,19 +147,19 @@ DeleteElement(JSContext *cx, HandleObjec
 extern bool
 DeleteSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid, bool *succeeded);
 
 extern bool
 DeleteGeneric(JSContext *cx, HandleObject obj, HandleId id, bool *succeeded);
 
 } /* namespace js::baseops */
 
-extern Class IntlClass;
-extern Class JSONClass;
-extern Class MathClass;
+extern const Class IntlClass;
+extern const Class JSONClass;
+extern const Class MathClass;
 
 class ArrayBufferObject;
 class GlobalObject;
 class MapObject;
 class NewObjectCache;
 class NormalArgumentsObject;
 class SetObject;
 class StrictArgumentsObject;
@@ -218,17 +218,17 @@ class JSObject : public js::ObjectImpl
     friend struct js::GCMarker;
     friend class  js::NewObjectCache;
     friend class js::Nursery;
 
     /* Make the type object to use for LAZY_TYPE objects. */
     static js::types::TypeObject *makeLazyType(JSContext *cx, js::HandleObject obj);
 
   public:
-    static js::Class class_;
+    static const js::Class class_;
 
     /*
      * Update the last property, keeping the number of allocated slots in sync
      * with the object's new slot span.
      */
     static bool setLastProperty(js::ExclusiveContext *cx,
                                 JS::HandleObject obj, js::HandleShape shape);
 
@@ -462,36 +462,36 @@ class JSObject : public js::ObjectImpl
     static inline bool getProto(JSContext *cx, js::HandleObject obj,
                                 js::MutableHandleObject protop);
 
     // uninlinedSetType() is the same as setType(), but not inlined.
     inline void setType(js::types::TypeObject *newType);
     void uninlinedSetType(js::types::TypeObject *newType);
 
 #ifdef DEBUG
-    bool hasNewType(js::Class *clasp, js::types::TypeObject *newType);
+    bool hasNewType(const js::Class *clasp, js::types::TypeObject *newType);
 #endif
 
     /*
      * Mark an object that has been iterated over and is a singleton. We need
      * to recover this information in the object's type information after it
      * is purged on GC.
      */
     bool setIteratedSingleton(js::ExclusiveContext *cx) {
         return setFlag(cx, js::BaseShape::ITERATED_SINGLETON);
     }
 
     /*
      * Mark an object as requiring its default 'new' type to have unknown
      * properties.
      */
-    static bool setNewTypeUnknown(JSContext *cx, js::Class *clasp, JS::HandleObject obj);
+    static bool setNewTypeUnknown(JSContext *cx, const js::Class *clasp, JS::HandleObject obj);
 
     /* Set a new prototype for an object with a singleton type. */
-    bool splicePrototype(JSContext *cx, js::Class *clasp, js::Handle<js::TaggedProto> proto);
+    bool splicePrototype(JSContext *cx, const js::Class *clasp, js::Handle<js::TaggedProto> proto);
 
     /*
      * For bootstrapping, whether to splice a prototype for Function.prototype
      * or the global object.
      */
     bool shouldSplicePrototype(JSContext *cx);
 
     /*
@@ -1189,20 +1189,20 @@ template <AllowGC allowGC>
 extern bool
 HasOwnProperty(JSContext *cx, LookupGenericOp lookup,
                typename MaybeRooted<JSObject*, allowGC>::HandleType obj,
                typename MaybeRooted<jsid, allowGC>::HandleType id,
                typename MaybeRooted<JSObject*, allowGC>::MutableHandleType objp,
                typename MaybeRooted<Shape*, allowGC>::MutableHandleType propp);
 
 bool
-IsStandardClassResolved(JSObject *obj, js::Class *clasp);
+IsStandardClassResolved(JSObject *obj, const js::Class *clasp);
 
 void
-MarkStandardClassInitializedNoProto(JSObject *obj, js::Class *clasp);
+MarkStandardClassInitializedNoProto(JSObject *obj, const js::Class *clasp);
 
 typedef JSObject *(*ClassInitializerOp)(JSContext *cx, JS::HandleObject obj);
 
 } /* namespace js */
 
 /*
  * Select Object.prototype method names shared between jsapi.cpp and jsobj.cpp.
  */
@@ -1237,17 +1237,17 @@ extern JSProtoKey
 js_IdentifyClassPrototype(JSObject *obj);
 
 /*
  * If protoKey is not JSProto_Null, then clasp is ignored. If protoKey is
  * JSProto_Null, clasp must non-null.
  */
 bool
 js_FindClassObject(js::ExclusiveContext *cx, JSProtoKey protoKey, js::MutableHandleValue vp,
-                   js::Class *clasp = NULL);
+                   const js::Class *clasp = NULL);
 
 /*
  * Find or create a property named by id in obj's scope, with the given getter
  * and setter, slot, attributes, and other members.
  */
 extern js::Shape *
 js_AddNativeProperty(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
                      JSPropertyOp getter, JSStrictPropertyOp setter, uint32_t slot,
@@ -1308,17 +1308,17 @@ CreateThisForFunctionWithProto(JSContext
                                NewObjectKind newKind = GenericObject);
 
 // Specialized call for constructing |this| with a known function callee.
 extern JSObject *
 CreateThisForFunction(JSContext *cx, js::HandleObject callee, bool newType);
 
 // Generic call for constructing |this|.
 extern JSObject *
-CreateThis(JSContext *cx, js::Class *clasp, js::HandleObject callee);
+CreateThis(JSContext *cx, const js::Class *clasp, js::HandleObject callee);
 
 extern JSObject *
 CloneObject(JSContext *cx, HandleObject obj, Handle<js::TaggedProto> proto, HandleObject parent);
 
 /*
  * Flags for the defineHow parameter of js_DefineNativeProperty.
  */
 const unsigned DNP_DONT_PURGE   = 1;   /* suppress js_PurgeScopeChain */
@@ -1528,26 +1528,26 @@ js_InferFlags(JSContext *cx, unsigned de
  * If protoKey is not JSProto_Null, then clasp is ignored. If protoKey is
  * JSProto_Null, clasp must non-null.
  *
  * If protoKey is constant and scope is non-null, use GlobalObject's prototype
  * methods instead.
  */
 extern bool
 js_GetClassPrototype(js::ExclusiveContext *cx, JSProtoKey protoKey, js::MutableHandleObject protop,
-                     js::Class *clasp = NULL);
+                     const js::Class *clasp = NULL);
 
 namespace js {
 
 JSObject *
 GetClassPrototypePure(GlobalObject *global, JSProtoKey protoKey);
 
 extern bool
 SetClassAndProto(JSContext *cx, HandleObject obj,
-                 Class *clasp, Handle<TaggedProto> proto, bool checkForCycles);
+                 const Class *clasp, Handle<TaggedProto> proto, bool checkForCycles);
 
 extern JSObject *
 NonNullObject(JSContext *cx, const Value &v);
 
 extern const char *
 InformalValueTypeName(const Value &v);
 
 extern bool
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -79,17 +79,17 @@ JSObject::finalize(js::FreeOp *fop)
 
 #ifdef DEBUG
     JS_ASSERT(isTenured());
     if (!IsBackgroundFinalized(tenuredGetAllocKind())) {
         /* Assert we're on the main thread. */
         JS_ASSERT(CurrentThreadCanAccessRuntime(fop->runtime()));
     }
 #endif
-    js::Class *clasp = getClass();
+    const js::Class *clasp = getClass();
     if (clasp->finalize)
         clasp->finalize(fop, this);
 
     finish(fop);
 }
 
 inline void
 JSObject::setLastPropertyInfallible(js::Shape *shape)
@@ -649,17 +649,17 @@ IsNativeFunction(const js::Value &v, JSN
  * When we have an object of a builtin class, we don't quite know what its
  * valueOf/toString methods are, since these methods may have been overwritten
  * or shadowed. However, we can still do better than the general case by
  * hard-coding the necessary properties for us to find the native we expect.
  *
  * TODO: a per-thread shape-based cache would be faster and simpler.
  */
 static JS_ALWAYS_INLINE bool
-ClassMethodIsNative(JSContext *cx, JSObject *obj, Class *clasp, jsid methodid, JSNative native)
+ClassMethodIsNative(JSContext *cx, JSObject *obj, const Class *clasp, jsid methodid, JSNative native)
 {
     JS_ASSERT(!obj->is<ProxyObject>());
     JS_ASSERT(obj->getClass() == clasp);
 
     Value v;
     if (!HasDataProperty(cx, obj, methodid, &v)) {
         JSObject *proto = obj->getProto();
         if (!proto || proto->getClass() != clasp || !HasDataProperty(cx, proto, methodid, &v))
@@ -752,47 +752,47 @@ class AutoPropDescArrayRooter : private 
     SkipRoot skip;
 };
 
 /*
  * Make an object with the specified prototype. If parent is null, it will
  * default to the prototype's global if the prototype is non-null.
  */
 JSObject *
-NewObjectWithGivenProto(ExclusiveContext *cx, js::Class *clasp, TaggedProto proto, JSObject *parent,
+NewObjectWithGivenProto(ExclusiveContext *cx, const js::Class *clasp, TaggedProto proto, JSObject *parent,
                         gc::AllocKind allocKind, NewObjectKind newKind);
 
 inline JSObject *
-NewObjectWithGivenProto(ExclusiveContext *cx, js::Class *clasp, TaggedProto proto, JSObject *parent,
+NewObjectWithGivenProto(ExclusiveContext *cx, const js::Class *clasp, TaggedProto proto, JSObject *parent,
                         NewObjectKind newKind = GenericObject)
 {
     gc::AllocKind allocKind = gc::GetGCObjectKind(clasp);
     return NewObjectWithGivenProto(cx, clasp, proto, parent, allocKind, newKind);
 }
 
 inline JSObject *
-NewObjectWithGivenProto(ExclusiveContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
+NewObjectWithGivenProto(ExclusiveContext *cx, const js::Class *clasp, JSObject *proto, JSObject *parent,
                         NewObjectKind newKind = GenericObject)
 {
     return NewObjectWithGivenProto(cx, clasp, TaggedProto(proto), parent, newKind);
 }
 
 inline JSProtoKey
-GetClassProtoKey(js::Class *clasp)
+GetClassProtoKey(const js::Class *clasp)
 {
     JSProtoKey key = JSCLASS_CACHED_PROTO_KEY(clasp);
     if (key != JSProto_Null)
         return key;
     if (clasp->flags & JSCLASS_IS_ANONYMOUS)
         return JSProto_Object;
     return JSProto_Null;
 }
 
 inline bool
-FindProto(ExclusiveContext *cx, js::Class *clasp, MutableHandleObject proto)
+FindProto(ExclusiveContext *cx, const js::Class *clasp, MutableHandleObject proto)
 {
     JSProtoKey protoKey = GetClassProtoKey(clasp);
     if (!js_GetClassPrototype(cx, protoKey, proto, clasp))
         return false;
     if (!proto && !js_GetClassPrototype(cx, JSProto_Object, proto))
         return false;
     return true;
 }
@@ -810,47 +810,47 @@ FindProto(ExclusiveContext *cx, js::Clas
  * else
  *   Object.prototype.
  *
  * The class prototype will be fetched from the parent's global. If global is
  * null, the context's active global will be used, and the resulting object's
  * parent will be that global.
  */
 JSObject *
-NewObjectWithClassProtoCommon(ExclusiveContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
+NewObjectWithClassProtoCommon(ExclusiveContext *cx, const js::Class *clasp, JSObject *proto, JSObject *parent,
                               gc::AllocKind allocKind, NewObjectKind newKind);
 
 inline JSObject *
-NewObjectWithClassProto(ExclusiveContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
+NewObjectWithClassProto(ExclusiveContext *cx, const js::Class *clasp, JSObject *proto, JSObject *parent,
                         gc::AllocKind allocKind, NewObjectKind newKind = GenericObject)
 {
     return NewObjectWithClassProtoCommon(cx, clasp, proto, parent, allocKind, newKind);
 }
 
 inline JSObject *
-NewObjectWithClassProto(ExclusiveContext *cx, js::Class *clasp, JSObject *proto, JSObject *parent,
+NewObjectWithClassProto(ExclusiveContext *cx, const js::Class *clasp, JSObject *proto, JSObject *parent,
                         NewObjectKind newKind = GenericObject)
 {
     gc::AllocKind allocKind = gc::GetGCObjectKind(clasp);
     return NewObjectWithClassProto(cx, clasp, proto, parent, allocKind, newKind);
 }
 
 /*
  * Create a native instance of the given class with parent and proto set
  * according to the context's active global.
  */
 inline JSObject *
-NewBuiltinClassInstance(ExclusiveContext *cx, Class *clasp, gc::AllocKind allocKind,
+NewBuiltinClassInstance(ExclusiveContext *cx, const Class *clasp, gc::AllocKind allocKind,
                         NewObjectKind newKind = GenericObject)
 {
     return NewObjectWithClassProto(cx, clasp, NULL, NULL, allocKind, newKind);
 }
 
 inline JSObject *
-NewBuiltinClassInstance(ExclusiveContext *cx, Class *clasp, NewObjectKind newKind = GenericObject)
+NewBuiltinClassInstance(ExclusiveContext *cx, const Class *clasp, NewObjectKind newKind = GenericObject)
 {
     gc::AllocKind allocKind = gc::GetGCObjectKind(clasp);
     return NewBuiltinClassInstance(cx, clasp, allocKind, newKind);
 }
 
 // Used to optimize calls to (new Object())
 bool
 NewObjectScriptedCall(JSContext *cx, MutableHandleObject obj);
@@ -969,17 +969,17 @@ static JS_ALWAYS_INLINE bool
 ValueIsSpecial(JSObject *obj, MutableHandleValue propval, MutableHandle<SpecialId> sidp,
                JSContext *cx)
 {
     return false;
 }
 
 JSObject *
 DefineConstructorAndPrototype(JSContext *cx, HandleObject obj, JSProtoKey key, HandleAtom atom,
-                              JSObject *protoProto, Class *clasp,
+                              JSObject *protoProto, const Class *clasp,
                               Native constructor, unsigned nargs,
                               const JSPropertySpec *ps, const JSFunctionSpec *fs,
                               const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs,
                               JSObject **ctorp = NULL,
                               gc::AllocKind ctorKind = JSFunction::FinalizeKind);
 
 static JS_ALWAYS_INLINE bool
 NewObjectMetadata(ExclusiveContext *cxArg, JSObject **pmetadata)
@@ -1036,15 +1036,15 @@ DefineProperty(ExclusiveContext *cx, Han
 }
 
 } /* namespace baseops */
 
 } /* namespace js */
 
 extern JSObject *
 js_InitClass(JSContext *cx, js::HandleObject obj, JSObject *parent_proto,
-             js::Class *clasp, JSNative constructor, unsigned nargs,
+             const js::Class *clasp, JSNative constructor, unsigned nargs,
              const JSPropertySpec *ps, const JSFunctionSpec *fs,
              const JSPropertySpec *static_ps, const JSFunctionSpec *static_fs,
              JSObject **ctorp = NULL,
              js::gc::AllocKind ctorKind = JSFunction::FinalizeKind);
 
 #endif /* jsobjinlines_h */
--- a/js/src/json.cpp
+++ b/js/src/json.cpp
@@ -28,17 +28,17 @@
 
 using namespace js;
 using namespace js::gc;
 using namespace js::types;
 
 using mozilla::IsFinite;
 using mozilla::Maybe;
 
-Class js::JSONClass = {
+const Class js::JSONClass = {
     js_JSON_str,
     JSCLASS_HAS_CACHED_PROTO(JSProto_JSON),
     JS_PropertyStub,        /* addProperty */
     JS_DeletePropertyStub,  /* delProperty */
     JS_PropertyStub,        /* getProperty */
     JS_StrictPropertyStub,  /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/jsproxy.cpp
+++ b/js/src/jsproxy.cpp
@@ -3017,17 +3017,17 @@ proxy_HasInstance(JSContext *cx, HandleO
     {                                               \
         NULL,                /* outerObject */      \
         NULL,                /* innerObject */      \
         NULL,                /* iteratorObject */   \
         false,               /* isWrappedNative */  \
         proxy_WeakmapKeyDelegate                    \
     }
 
-Class js::ObjectProxyObject::class_ = {
+const Class js::ObjectProxyObject::class_ = {
     "Proxy",
     Class::NON_NATIVE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(4) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Proxy),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
@@ -3063,19 +3063,19 @@ Class js::ObjectProxyObject::class_ = {
         proxy_DeleteProperty,
         proxy_DeleteElement,
         proxy_DeleteSpecial,
         NULL,                /* enumerate       */
         NULL,                /* thisObject      */
     }
 };
 
-Class* const js::ObjectProxyClassPtr = &ObjectProxyObject::class_;
-
-Class js::OuterWindowProxyObject::class_ = {
+const Class* const js::ObjectProxyClassPtr = &ObjectProxyObject::class_;
+
+const Class js::OuterWindowProxyObject::class_ = {
     "Proxy",
     Class::NON_NATIVE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(4),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
@@ -3116,17 +3116,17 @@ Class js::OuterWindowProxyObject::class_
         proxy_DeleteProperty,
         proxy_DeleteElement,
         proxy_DeleteSpecial,
         NULL,                /* enumerate       */
         NULL,                /* thisObject      */
     }
 };
 
-Class* const js::OuterWindowProxyClassPtr = &OuterWindowProxyObject::class_;
+const Class* const js::OuterWindowProxyClassPtr = &OuterWindowProxyObject::class_;
 
 static bool
 proxy_Call(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     RootedObject proxy(cx, &args.callee());
     JS_ASSERT(proxy->is<ProxyObject>());
     return Proxy::call(cx, proxy, args);
@@ -3136,17 +3136,17 @@ static bool
 proxy_Construct(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     RootedObject proxy(cx, &args.callee());
     JS_ASSERT(proxy->is<ProxyObject>());
     return Proxy::construct(cx, proxy, args);
 }
 
-Class js::FunctionProxyObject::class_ = {
+const Class js::FunctionProxyObject::class_ = {
     "Proxy",
     Class::NON_NATIVE | JSCLASS_IMPLEMENTS_BARRIERS | JSCLASS_HAS_RESERVED_SLOTS(6),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
@@ -3181,28 +3181,28 @@ Class js::FunctionProxyObject::class_ = 
         proxy_DeleteProperty,
         proxy_DeleteElement,
         proxy_DeleteSpecial,
         NULL,                /* enumerate       */
         NULL,                /* thisObject      */
     }
 };
 
-Class* const js::FunctionProxyClassPtr = &FunctionProxyObject::class_;
+const Class* const js::FunctionProxyClassPtr = &FunctionProxyObject::class_;
 
 /* static */ ProxyObject *
 ProxyObject::New(JSContext *cx, BaseProxyHandler *handler, HandleValue priv, TaggedProto proto_,
                  JSObject *parent_, ProxyCallable callable)
 {
     Rooted<TaggedProto> proto(cx, proto_);
     RootedObject parent(cx, parent_);
 
     JS_ASSERT_IF(proto.isObject(), cx->compartment() == proto.toObject()->compartment());
     JS_ASSERT_IF(parent, cx->compartment() == parent->compartment());
-    Class *clasp;
+    const Class *clasp;
     if (callable)
         clasp = &FunctionProxyObject::class_;
     else
         clasp = handler->isOuterWindow() ? &OuterWindowProxyObject::class_
                                          : &ObjectProxyObject::class_;
 
     /*
      * Eagerly mark properties unknown for proxies, so we don't try to track
--- a/js/src/jsproxy.h
+++ b/js/src/jsproxy.h
@@ -275,19 +275,19 @@ class Proxy
     static bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp);
     static bool getPrototypeOf(JSContext *cx, HandleObject proxy, MutableHandleObject protop);
 
     static JSObject * const LazyProto;
 };
 
 // These are equal to |&{Function,Object,OuterWindow}ProxyObject::class_|.  Use
 // them in places where you don't want to #include vm/ProxyObject.h.
-extern JS_FRIEND_DATA(js::Class* const) FunctionProxyClassPtr;
-extern JS_FRIEND_DATA(js::Class* const) ObjectProxyClassPtr;
-extern JS_FRIEND_DATA(js::Class* const) OuterWindowProxyClassPtr;
+extern JS_FRIEND_DATA(const js::Class* const) FunctionProxyClassPtr;
+extern JS_FRIEND_DATA(const js::Class* const) ObjectProxyClassPtr;
+extern JS_FRIEND_DATA(const js::Class* const) OuterWindowProxyClassPtr;
 
 inline bool IsObjectProxyClass(const Class *clasp)
 {
     return clasp == ObjectProxyClassPtr || clasp == OuterWindowProxyClassPtr;
 }
 
 inline bool IsFunctionProxyClass(const Class *clasp)
 {
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -937,17 +937,17 @@ ScriptSourceObject::setSource(ScriptSour
 
 void
 ScriptSourceObject::finalize(FreeOp *fop, JSObject *obj)
 {
     // ScriptSource::setSource automatically takes care of the refcount
     obj->as<ScriptSourceObject>().setSource(NULL);
 }
 
-Class ScriptSourceObject::class_ = {
+const Class ScriptSourceObject::class_ = {
     "ScriptSource",
     JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_IS_ANONYMOUS,
     JS_PropertyStub,        /* addProperty */
     JS_DeletePropertyStub,  /* delProperty */
     JS_PropertyStub,        /* getProperty */
     JS_StrictPropertyStub,  /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -397,17 +397,17 @@ class ScriptSourceHolder
     {
         ss->decref();
     }
 };
 
 class ScriptSourceObject : public JSObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 
     static void finalize(FreeOp *fop, JSObject *obj);
     static ScriptSourceObject *create(ExclusiveContext *cx, ScriptSource *source);
 
     ScriptSource *source() {
         return static_cast<ScriptSource *>(getReservedSlot(SOURCE_SLOT).toPrivate());
     }
 
--- a/js/src/jsstr.cpp
+++ b/js/src/jsstr.cpp
@@ -402,17 +402,17 @@ str_resolve(JSContext *cx, HandleObject 
         {
             return false;
         }
         objp.set(obj);
     }
     return true;
 }
 
-Class StringObject::class_ = {
+const Class StringObject::class_ = {
     js_String_str,
     JSCLASS_HAS_RESERVED_SLOTS(StringObject::RESERVED_SLOTS) |
     JSCLASS_NEW_RESOLVE | JSCLASS_HAS_CACHED_PROTO(JSProto_String),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     str_enumerate,
@@ -2800,17 +2800,17 @@ LambdaIsGetElem(JSContext *cx, JSObject 
     if (JSOp(*pc) != JSOP_RETURN)
         return true;
 
     /* 'b' must behave like a normal object. */
     if (!b.isObject())
         return true;
 
     JSObject &bobj = b.toObject();
-    Class *clasp = bobj.getClass();
+    const Class *clasp = bobj.getClass();
     if (!clasp->isNative() || clasp->ops.lookupProperty || clasp->ops.getProperty)
         return true;
 
     pobj.set(&bobj);
     return true;
 }
 
 bool
--- a/js/src/jsweakmap.cpp
+++ b/js/src/jsweakmap.cpp
@@ -383,17 +383,17 @@ WeakMap_construct(JSContext *cx, unsigne
     JSObject *obj = NewBuiltinClassInstance(cx, &WeakMapObject::class_);
     if (!obj)
         return false;
 
     vp->setObject(*obj);
     return true;
 }
 
-Class WeakMapObject::class_ = {
+const Class WeakMapObject::class_ = {
     "WeakMap",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_CACHED_PROTO(JSProto_WeakMap),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
--- a/js/src/jsworkers.cpp
+++ b/js/src/jsworkers.cpp
@@ -161,17 +161,17 @@ js::CancelOffThreadIonCompile(JSCompartm
         if (CompiledScriptMatches(compartment, script, builder->script())) {
             jit::FinishOffThreadBuilder(builder);
             compilations[i--] = compilations.back();
             compilations.popBack();
         }
     }
 }
 
-static JSClass workerGlobalClass = {
+static const JSClass workerGlobalClass = {
     "internal-worker-global", JSCLASS_GLOBAL_FLAGS,
     JS_PropertyStub,  JS_DeletePropertyStub,
     JS_PropertyStub,  JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub,
     JS_ConvertStub,   NULL
 };
 
 ParseTask::ParseTask(ExclusiveContext *cx, const CompileOptions &options,
--- a/js/src/perf/jsperf.cpp
+++ b/js/src/perf/jsperf.cpp
@@ -155,17 +155,17 @@ static const struct pm_const {
     { 0, PerfMeasurement::EventMask(0) }
 };
 
 #undef CONSTANT
 
 static bool pm_construct(JSContext* cx, unsigned argc, jsval* vp);
 static void pm_finalize(JSFreeOp* fop, JSObject* obj);
 
-static JSClass pm_class = {
+static const JSClass pm_class = {
     "PerfMeasurement", JSCLASS_HAS_PRIVATE,
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, pm_finalize
 };
 
 // Constructor and destructor
 
 static bool
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -606,17 +606,17 @@ MapContextOptionNameToFlag(JSContext* cx
         JS_ReportOutOfMemory(cx);
     } else {
         JS_ReportError(cx, msg);
         free(msg);
     }
     return 0;
 }
 
-extern JSClass global_class;
+extern const JSClass global_class;
 
 static bool
 Version(JSContext *cx, unsigned argc, jsval *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     JSVersion origVersion = JS_GetVersion(cx);
     if (args.length() == 0 || JSVAL_IS_VOID(args[0])) {
         /* Get version. */
@@ -2477,17 +2477,17 @@ sandbox_resolve(JSContext *cx, HandleObj
             objp.set(obj);
             return true;
         }
     }
     objp.set(NULL);
     return true;
 }
 
-static JSClass sandbox_class = {
+static const JSClass sandbox_class = {
     "sandbox",
     JSCLASS_NEW_RESOLVE | JSCLASS_GLOBAL_FLAGS,
     JS_PropertyStub,   JS_DeletePropertyStub,
     JS_PropertyStub,   JS_StrictPropertyStub,
     sandbox_enumerate, (JSResolveOp)sandbox_resolve,
     JS_ConvertStub
 };
 
@@ -2740,17 +2740,17 @@ resolver_enumerate(JSContext *cx, Handle
     RootedObject ignore(cx);
     for (size_t i = 0; ok && i < ida.length(); i++) {
         Rooted<jsid> id(cx, ida[i]);
         ok = CopyProperty(cx, obj, referent, id, 0, &ignore);
     }
     return ok;
 }
 
-static JSClass resolver_class = {
+static const JSClass resolver_class = {
     "resolver",
     JSCLASS_NEW_RESOLVE | JSCLASS_HAS_RESERVED_SLOTS(1),
     JS_PropertyStub,   JS_DeletePropertyStub,
     JS_PropertyStub,   JS_StrictPropertyStub,
     resolver_enumerate, (JSResolveOp)resolver_resolve,
     JS_ConvertStub
 };
 
@@ -3646,17 +3646,17 @@ GetMaxArgs(JSContext *cx, unsigned arg, 
 {
     JS_SET_RVAL(cx, vp, INT_TO_JSVAL(ARGS_LENGTH_MAX));
     return true;
 }
 
 static bool
 ObjectEmulatingUndefined(JSContext *cx, unsigned argc, jsval *vp)
 {
-    static JSClass cls = {
+    static const JSClass cls = {
         "ObjectEmulatingUndefined",
         JSCLASS_EMULATES_UNDEFINED,
         JS_PropertyStub,
         JS_DeletePropertyStub,
         JS_PropertyStub,
         JS_StrictPropertyStub,
         JS_EnumerateStub,
         JS_ResolveStub,
@@ -4303,17 +4303,17 @@ its_convert(JSContext *cx, HandleObject 
 
 static void
 its_finalize(JSFreeOp *fop, JSObject *obj)
 {
     if (its_noisy)
         fprintf(gOutFile, "finalizing it\n");
 }
 
-static JSClass its_class = {
+static const JSClass its_class = {
     "It", JSCLASS_NEW_RESOLVE | JSCLASS_NEW_ENUMERATE | JSCLASS_HAS_RESERVED_SLOTS(1),
     its_addProperty,  its_delProperty,  its_getProperty,  its_setProperty,
     (JSEnumerateOp)its_enumerate, (JSResolveOp)its_resolve,
     its_convert,      its_finalize,
 };
 
 static bool
 its_getter(JSContext *cx, HandleObject obj, HandleId id, MutableHandleValue vp)
@@ -4536,17 +4536,17 @@ global_resolve(JSContext *cx, HandleObje
     }
     JS_free(cx, path);
     return ok;
 #else
     return true;
 #endif
 }
 
-JSClass global_class = {
+const JSClass global_class = {
     "global", JSCLASS_NEW_RESOLVE | JSCLASS_GLOBAL_FLAGS,
     JS_PropertyStub,  JS_DeletePropertyStub,
     JS_PropertyStub,  JS_StrictPropertyStub,
     global_enumerate, (JSResolveOp) global_resolve,
     JS_ConvertStub,   NULL
 };
 
 static bool
@@ -4642,17 +4642,17 @@ env_resolve(JSContext *cx, HandleObject 
                                NULL, NULL, JSPROP_ENUMERATE)) {
             return false;
         }
         objp.set(obj);
     }
     return true;
 }
 
-static JSClass env_class = {
+static const JSClass env_class = {
     "environment", JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
     JS_PropertyStub,  JS_DeletePropertyStub,
     JS_PropertyStub,  env_setProperty,
     env_enumerate, (JSResolveOp) env_resolve,
     JS_ConvertStub
 };
 
 /*
@@ -4667,17 +4667,17 @@ dom_genericGetter(JSContext* cx, unsigne
 
 static bool
 dom_genericSetter(JSContext* cx, unsigned argc, JS::Value *vp);
 
 static bool
 dom_genericMethod(JSContext *cx, unsigned argc, JS::Value *vp);
 
 #ifdef DEBUG
-static JSClass *GetDomClass();
+static const JSClass *GetDomClass();
 #endif
 
 static bool
 dom_get_x(JSContext* cx, HandleObject obj, void *self, JSJitGetterCallArgs args)
 {
     JS_ASSERT(JS_GetClass(obj) == GetDomClass());
     JS_ASSERT(self == (void *)0x1234);
     args.rval().set(JS_NumberValue(double(3.14)));
@@ -4739,17 +4739,17 @@ static const JSPropertySpec dom_props[] 
     {NULL,0,0,JSOP_NULLWRAPPER, JSOP_NULLWRAPPER}
 };
 
 static const JSFunctionSpec dom_methods[] = {
     JS_FNINFO("doFoo", dom_genericMethod, &doFoo_methodinfo, 3, JSPROP_ENUMERATE),
     JS_FS_END
 };
 
-static JSClass dom_class = {
+static const JSClass dom_class = {
     "FakeDOMObject", JSCLASS_IS_DOMJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(2),
     JS_PropertyStub,       /* addProperty */
     JS_DeletePropertyStub, /* delProperty */
     JS_PropertyStub,       /* getProperty */
     JS_StrictPropertyStub, /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub,
@@ -4758,17 +4758,17 @@ static JSClass dom_class = {
     NULL,                  /* call */
     NULL,                  /* hasInstance */
     NULL,                  /* construct */
     NULL,                  /* trace */
     JSCLASS_NO_INTERNAL_MEMBERS
 };
 
 #ifdef DEBUG
-static JSClass *GetDomClass() {
+static const JSClass *GetDomClass() {
     return &dom_class;
 }
 #endif
 
 static bool
 dom_genericGetter(JSContext *cx, unsigned argc, JS::Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
@@ -5320,17 +5320,17 @@ JSPrincipals shellTrustedPrincipals = { 
 
 bool
 CheckObjectAccess(JSContext *cx, HandleObject obj, HandleId id, JSAccessMode mode,
                   MutableHandleValue vp)
 {
     return true;
 }
 
-JSSecurityCallbacks securityCallbacks = {
+const JSSecurityCallbacks securityCallbacks = {
     CheckObjectAccess,
     NULL
 };
 
 /* Pretend we can always preserve wrappers for dummy DOM objects. */
 static bool
 DummyPreserveWrapperCallback(JSContext *cx, JSObject *obj)
 {
--- a/js/src/vm/ArgumentsObject.cpp
+++ b/js/src/vm/ArgumentsObject.cpp
@@ -171,17 +171,17 @@ template <typename CopyArgs>
 ArgumentsObject::create(JSContext *cx, HandleScript script, HandleFunction callee, unsigned numActuals,
                         CopyArgs &copy)
 {
     RootedObject proto(cx, callee->global().getOrCreateObjectPrototype(cx));
     if (!proto)
         return NULL;
 
     bool strict = callee->strict();
-    Class *clasp = strict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
+    const Class *clasp = strict ? &StrictArgumentsObject::class_ : &NormalArgumentsObject::class_;
 
     RootedTypeObject type(cx, cx->getNewType(clasp, proto.get()));
     if (!type)
         return NULL;
 
     JSObject *metadata = NULL;
     if (!NewObjectMetadata(cx, &metadata))
         return NULL;
@@ -573,17 +573,17 @@ ArgumentsObject::trace(JSTracer *trc, JS
 }
 
 /*
  * The classes below collaborate to lazily reflect and synchronize actual
  * argument values, argument count, and callee function object stored in a
  * StackFrame with their corresponding property values in the frame's
  * arguments object.
  */
-Class NormalArgumentsObject::class_ = {
+const Class NormalArgumentsObject::class_ = {
     "Arguments",
     JSCLASS_NEW_RESOLVE | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(NormalArgumentsObject::RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Object) | JSCLASS_BACKGROUND_FINALIZE,
     JS_PropertyStub,         /* addProperty */
     args_delProperty,
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
@@ -604,17 +604,17 @@ Class NormalArgumentsObject::class_ = {
     }
 };
 
 /*
  * Strict mode arguments is significantly less magical than non-strict mode
  * arguments, so it is represented by a different class while sharing some
  * functionality.
  */
-Class StrictArgumentsObject::class_ = {
+const Class StrictArgumentsObject::class_ = {
     "Arguments",
     JSCLASS_NEW_RESOLVE | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(StrictArgumentsObject::RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Object) | JSCLASS_BACKGROUND_FINALIZE,
     JS_PropertyStub,         /* addProperty */
     args_delProperty,
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
--- a/js/src/vm/ArgumentsObject.h
+++ b/js/src/vm/ArgumentsObject.h
@@ -277,17 +277,17 @@ class ArgumentsObject : public JSObject
     static void MaybeForwardToCallObject(jit::IonJSFrameLayout *frame, HandleObject callObj,
                                          JSObject *obj, ArgumentsData *data);
 #endif
 };
 
 class NormalArgumentsObject : public ArgumentsObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 
     /*
      * Stores arguments.callee, or MagicValue(JS_ARGS_HOLE) if the callee has
      * been cleared.
      */
     const js::Value &callee() const {
         return data()->callee;
     }
@@ -296,17 +296,17 @@ class NormalArgumentsObject : public Arg
     void clearCallee() {
         data()->callee.set(zone(), MagicValue(JS_OVERWRITTEN_CALLEE));
     }
 };
 
 class StrictArgumentsObject : public ArgumentsObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 };
 
 } // namespace js
 
 template<>
 inline bool
 JSObject::is<js::ArgumentsObject>() const
 {
--- a/js/src/vm/ArrayObject.h
+++ b/js/src/vm/ArrayObject.h
@@ -9,17 +9,17 @@
 
 #include "jsobj.h"
 
 namespace js {
 
 class ArrayObject : public JSObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 
     bool lengthIsWritable() const {
         return !getElementsHeader()->hasNonwritableArrayLength();
     }
 
     uint32_t length() const {
         return getElementsHeader()->length;
     }
--- a/js/src/vm/BooleanObject.h
+++ b/js/src/vm/BooleanObject.h
@@ -15,17 +15,17 @@ namespace js {
 class BooleanObject : public JSObject
 {
     /* Stores this Boolean object's [[PrimitiveValue]]. */
     static const unsigned PRIMITIVE_VALUE_SLOT = 0;
 
   public:
     static const unsigned RESERVED_SLOTS = 1;
 
-    static Class class_;
+    static const Class class_;
 
     /*
      * Creates a new Boolean object boxing the given primitive bool.  The
      * object's [[Prototype]] is determined from context.
      */
     static inline BooleanObject *create(JSContext *cx, bool b);
 
     bool unbox() const {
--- a/js/src/vm/DateObject.h
+++ b/js/src/vm/DateObject.h
@@ -34,17 +34,17 @@ class DateObject : public JSObject
     static const uint32_t LOCAL_DAY_SLOT     = COMPONENTS_START_SLOT + 4;
     static const uint32_t LOCAL_HOURS_SLOT   = COMPONENTS_START_SLOT + 5;
     static const uint32_t LOCAL_MINUTES_SLOT = COMPONENTS_START_SLOT + 6;
     static const uint32_t LOCAL_SECONDS_SLOT = COMPONENTS_START_SLOT + 7;
 
     static const uint32_t RESERVED_SLOTS = LOCAL_SECONDS_SLOT + 1;
 
   public:
-    static Class class_;
+    static const Class class_;
 
     inline const js::Value &UTCTime() const {
         return getFixedSlot(UTC_TIME_SLOT);
     }
 
     // Set UTC time to a given time and invalidate cached local time.
     void setUTCTime(double t, Value *vp = NULL);
 
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -32,55 +32,55 @@ using namespace js;
 
 using js::frontend::IsIdentifier;
 using mozilla::ArrayLength;
 using mozilla::Maybe;
 
 
 /*** Forward declarations ************************************************************************/
 
-extern Class DebuggerFrame_class;
+extern const Class DebuggerFrame_class;
 
 enum {
     JSSLOT_DEBUGFRAME_OWNER,
     JSSLOT_DEBUGFRAME_ARGUMENTS,
     JSSLOT_DEBUGFRAME_ONSTEP_HANDLER,
     JSSLOT_DEBUGFRAME_ONPOP_HANDLER,
     JSSLOT_DEBUGFRAME_COUNT
 };
 
-extern Class DebuggerArguments_class;
+extern const Class DebuggerArguments_class;
 
 enum {
     JSSLOT_DEBUGARGUMENTS_FRAME,
     JSSLOT_DEBUGARGUMENTS_COUNT
 };
 
-extern Class DebuggerEnv_class;
+extern const Class DebuggerEnv_class;
 
 enum {
     JSSLOT_DEBUGENV_OWNER,
     JSSLOT_DEBUGENV_COUNT
 };
 
-extern Class DebuggerObject_class;
+extern const Class DebuggerObject_class;
 
 enum {
     JSSLOT_DEBUGOBJECT_OWNER,
     JSSLOT_DEBUGOBJECT_COUNT
 };
 
-extern Class DebuggerScript_class;
+extern const Class DebuggerScript_class;
 
 enum {
     JSSLOT_DEBUGSCRIPT_OWNER,
     JSSLOT_DEBUGSCRIPT_COUNT
 };
 
-extern Class DebuggerSource_class;
+extern const Class DebuggerSource_class;
 
 enum {
     JSSLOT_DEBUGSOURCE_OWNER,
     JSSLOT_DEBUGSOURCE_COUNT
 };
 
 
 /*** Utils ***************************************************************************************/
@@ -1668,17 +1668,17 @@ Debugger::finalize(FreeOp *fop, JSObject
 {
     Debugger *dbg = fromJSObject(obj);
     if (!dbg)
         return;
     JS_ASSERT(dbg->debuggees.empty());
     fop->delete_(dbg);
 }
 
-Class Debugger::jsclass = {
+const Class Debugger::jsclass = {
     "Debugger",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUG_COUNT),
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, Debugger::finalize,
     NULL,                 /* checkAccess */
     NULL,                 /* call        */
     NULL,                 /* hasInstance */
@@ -2715,17 +2715,17 @@ DebuggerScript_trace(JSTracer *trc, JSOb
 {
     /* This comes from a private pointer, so no barrier needed. */
     if (JSScript *script = GetScriptReferent(obj)) {
         MarkCrossCompartmentScriptUnbarriered(trc, obj, &script, "Debugger.Script referent");
         obj->setPrivateUnbarriered(script);
     }
 }
 
-Class DebuggerScript_class = {
+const Class DebuggerScript_class = {
     "Script",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGSCRIPT_COUNT),
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
     NULL,                 /* checkAccess */
     NULL,                 /* call        */
     NULL,                 /* hasInstance */
@@ -3605,17 +3605,17 @@ DebuggerSource_trace(JSTracer *trc, JSOb
      * is okay.
      */
     if (JSObject *referent = GetSourceReferent(obj)) {
         MarkCrossCompartmentObjectUnbarriered(trc, obj, &referent, "Debugger.Source referent");
         obj->setPrivateUnbarriered(referent);
     }
 }
 
-Class DebuggerSource_class = {
+const Class DebuggerSource_class = {
     "Source",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGSOURCE_COUNT),
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
     NULL,                 /* checkAccess */
     NULL,                 /* call        */
     NULL,                 /* hasInstance */
@@ -3760,17 +3760,17 @@ DebuggerFrame_freeScriptFrameIterData(Fr
 }
 
 static void
 DebuggerFrame_finalize(FreeOp *fop, JSObject *obj)
 {
     DebuggerFrame_freeScriptFrameIterData(fop, obj);
 }
 
-Class DebuggerFrame_class = {
+const Class DebuggerFrame_class = {
     "Frame", JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGFRAME_COUNT),
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, DebuggerFrame_finalize
 };
 
 static JSObject *
 CheckThisFrame(JSContext *cx, const CallArgs &args, const char *fnname, bool checkLive)
 {
@@ -3905,17 +3905,17 @@ DebuggerFrame_getOlder(JSContext *cx, un
             continue;
         if (dbg->observesFrame(iter.abstractFramePtr()))
             return dbg->getScriptFrame(cx, iter, args.rval());
     }
     args.rval().setNull();
     return true;
 }
 
-Class DebuggerArguments_class = {
+const Class DebuggerArguments_class = {
     "Arguments", JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGARGUMENTS_COUNT),
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
 /* The getter used for each element of frame.arguments. See DebuggerFrame_getArguments. */
 static bool
 DebuggerArguments_getArg(JSContext *cx, unsigned argc, Value *vp)
@@ -4390,17 +4390,17 @@ DebuggerObject_trace(JSTracer *trc, JSOb
      * is okay.
      */
     if (JSObject *referent = (JSObject *) obj->getPrivate()) {
         MarkCrossCompartmentObjectUnbarriered(trc, obj, &referent, "Debugger.Object referent");
         obj->setPrivateUnbarriered(referent);
     }
 }
 
-Class DebuggerObject_class = {
+const Class DebuggerObject_class = {
     "Object",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGOBJECT_COUNT),
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
     NULL,                 /* checkAccess */
     NULL,                 /* call        */
     NULL,                 /* hasInstance */
@@ -5207,17 +5207,17 @@ DebuggerEnv_trace(JSTracer *trc, JSObjec
      * is okay.
      */
     if (Env *referent = (JSObject *) obj->getPrivate()) {
         MarkCrossCompartmentObjectUnbarriered(trc, obj, &referent, "Debugger.Environment referent");
         obj->setPrivateUnbarriered(referent);
     }
 }
 
-Class DebuggerEnv_class = {
+const Class DebuggerEnv_class = {
     "Environment",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_DEBUGENV_COUNT),
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
     NULL,                 /* checkAccess */
     NULL,                 /* call        */
     NULL,                 /* hasInstance */
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -300,17 +300,17 @@ class Debugger : private mozilla::Linked
 
     GlobalObject *unwrapDebuggeeArgument(JSContext *cx, const Value &v);
 
     static void traceObject(JSTracer *trc, JSObject *obj);
     void trace(JSTracer *trc);
     static void finalize(FreeOp *fop, JSObject *obj);
     void markKeysInCompartment(JSTracer *tracer);
 
-    static Class jsclass;
+    static const Class jsclass;
 
     static Debugger *fromThisValue(JSContext *cx, const CallArgs &ca, const char *fnname);
     static bool getEnabled(JSContext *cx, unsigned argc, Value *vp);
     static bool setEnabled(JSContext *cx, unsigned argc, Value *vp);
     static bool getHookImpl(JSContext *cx, unsigned argc, Value *vp, Hook which);
     static bool setHookImpl(JSContext *cx, unsigned argc, Value *vp, Hook which);
     static bool getOnDebuggerStatement(JSContext *cx, unsigned argc, Value *vp);
     static bool setOnDebuggerStatement(JSContext *cx, unsigned argc, Value *vp);
--- a/js/src/vm/ErrorObject.h
+++ b/js/src/vm/ErrorObject.h
@@ -11,16 +11,16 @@
 
 struct JSExnPrivate;
 
 namespace js {
 
 class ErrorObject : public JSObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 
     JSExnPrivate *getExnPrivate() { return static_cast<JSExnPrivate*>(getPrivate()); }
 };
 
 } // namespace js
 
 #endif // vm_ErrorObject_h_
--- a/js/src/vm/GeneratorObject.h
+++ b/js/src/vm/GeneratorObject.h
@@ -9,24 +9,24 @@
 
 #include "jsobj.h"
 
 namespace js {
 
 class LegacyGeneratorObject : public JSObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 
     JSGenerator *getGenerator() { return static_cast<JSGenerator*>(getPrivate()); }
 };
 
 class StarGeneratorObject : public JSObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 
     JSGenerator *getGenerator() { return static_cast<JSGenerator*>(getPrivate()); }
 };
 
 } // namespace js
 
 #endif /* vm_GeneratorObject_h */
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -417,17 +417,17 @@ GlobalObject::initFunctionAndObjectClass
      * |Function.prototype| -- after all initialization, for simplicity.
      */
     RootedScript functionProtoScript(cx, functionProto->nonLazyScript());
     CallNewScriptHook(cx, functionProtoScript, functionProto);
     return functionProto;
 }
 
 GlobalObject *
-GlobalObject::create(JSContext *cx, Class *clasp)
+GlobalObject::create(JSContext *cx, const Class *clasp)
 {
     JS_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL);
 
     JSObject *obj = NewObjectWithGivenProto(cx, clasp, NULL, NULL, SingletonObject);
     if (!obj)
         return NULL;
 
     Rooted<GlobalObject *> global(cx, &obj->as<GlobalObject>());
@@ -507,41 +507,41 @@ GlobalObject::createConstructor(JSContex
                                 gc::AllocKind kind)
 {
     RootedAtom name(cx, nameArg);
     RootedObject self(cx, this);
     return NewFunction(cx, NullPtr(), ctor, length, JSFunction::NATIVE_CTOR, self, name, kind);
 }
 
 static JSObject *
-CreateBlankProto(JSContext *cx, Class *clasp, JSObject &proto, GlobalObject &global)
+CreateBlankProto(JSContext *cx, const Class *clasp, JSObject &proto, GlobalObject &global)
 {
     JS_ASSERT(clasp != &JSObject::class_);
     JS_ASSERT(clasp != &JSFunction::class_);
 
     RootedObject blankProto(cx, NewObjectWithGivenProto(cx, clasp, &proto, &global, SingletonObject));
     if (!blankProto)
         return NULL;
 
     return blankProto;
 }
 
 JSObject *
-GlobalObject::createBlankPrototype(JSContext *cx, Class *clasp)
+GlobalObject::createBlankPrototype(JSContext *cx, const Class *clasp)
 {
     Rooted<GlobalObject*> self(cx, this);
     JSObject *objectProto = getOrCreateObjectPrototype(cx);
     if (!objectProto)
         return NULL;
 
     return CreateBlankProto(cx, clasp, *objectProto, *self.get());
 }
 
 JSObject *
-GlobalObject::createBlankPrototypeInheriting(JSContext *cx, Class *clasp, JSObject &proto)
+GlobalObject::createBlankPrototypeInheriting(JSContext *cx, const Class *clasp, JSObject &proto)
 {
     return CreateBlankProto(cx, clasp, proto, *this);
 }
 
 bool
 js::LinkConstructorAndPrototype(JSContext *cx, JSObject *ctor_, JSObject *proto_)
 {
     RootedObject ctor(cx, ctor_), proto(cx, proto_);
@@ -570,17 +570,17 @@ js::DefinePropertiesAndBrand(JSContext *
 }
 
 static void
 GlobalDebuggees_finalize(FreeOp *fop, JSObject *obj)
 {
     fop->delete_((GlobalObject::DebuggerVector *) obj->getPrivate());
 }
 
-static Class
+static const Class
 GlobalDebuggees_class = {
     "GlobalDebuggee", JSCLASS_HAS_PRIVATE,
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, GlobalDebuggees_finalize
 };
 
 GlobalObject::DebuggerVector *
 GlobalObject::getDebuggers()
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -231,17 +231,17 @@ class GlobalObject : public JSObject
         JS_ASSERT(getSlotRef(CREATE_DATAVIEW_FOR_THIS).isUndefined());
         setSlot(CREATE_DATAVIEW_FOR_THIS, ObjectValue(*fun));
     }
 
     template<typename T>
     inline void setCreateArrayFromBuffer(Handle<JSFunction*> fun);
 
   public:
-    static GlobalObject *create(JSContext *cx, Class *clasp);
+    static GlobalObject *create(JSContext *cx, const Class *clasp);
 
     /*
      * Create a constructor function with the specified name and length using
      * ctor, a method which creates objects with the given class.
      */
     JSFunction *
     createConstructor(JSContext *cx, JSNative ctor, JSAtom *name, unsigned length,
                       gc::AllocKind kind = JSFunction::FinalizeKind);
@@ -249,23 +249,23 @@ class GlobalObject : public JSObject
     /*
      * Create an object to serve as [[Prototype]] for instances of the given
      * class, using |Object.prototype| as its [[Prototype]].  Users creating
      * prototype objects with particular internal structure (e.g. reserved
      * slots guaranteed to contain values of particular types) must immediately
      * complete the minimal initialization to make the returned object safe to
      * touch.
      */
-    JSObject *createBlankPrototype(JSContext *cx, js::Class *clasp);
+    JSObject *createBlankPrototype(JSContext *cx, const js::Class *clasp);
 
     /*
      * Identical to createBlankPrototype, but uses proto as the [[Prototype]]
      * of the returned blank prototype.
      */
-    JSObject *createBlankPrototypeInheriting(JSContext *cx, js::Class *clasp, JSObject &proto);
+    JSObject *createBlankPrototypeInheriting(JSContext *cx, const js::Class *clasp, JSObject &proto);
 
     JSObject *getOrCreateObjectPrototype(JSContext *cx) {
         if (functionObjectClassesInitialized())
             return &getPrototype(JSProto_Object).toObject();
         Rooted<GlobalObject*> self(cx, this);
         if (!initFunctionAndObjectClasses(cx))
             return NULL;
         return &self->getPrototype(JSProto_Object).toObject();
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -163,17 +163,17 @@ js::BoxNonStrictThis(JSContext *cx, cons
     return true;
 }
 
 #if JS_HAS_NO_SUCH_METHOD
 
 static const uint32_t JSSLOT_FOUND_FUNCTION = 0;
 static const uint32_t JSSLOT_SAVED_ID = 1;
 
-static Class js_NoSuchMethodClass = {
+static const Class js_NoSuchMethodClass = {
     "NoSuchMethod",
     JSCLASS_HAS_RESERVED_SLOTS(2) | JSCLASS_IS_ANONYMOUS,
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
 };
 
 /*
  * When JSOP_CALLPROP or JSOP_CALLELEM does not find the method property of
@@ -452,17 +452,17 @@ js::Invoke(JSContext *cx, CallArgs args,
 
     /* MaybeConstruct is a subset of InitialFrameFlags */
     InitialFrameFlags initial = (InitialFrameFlags) construct;
 
     if (args.calleev().isPrimitive())
         return ReportIsNotFunction(cx, args.calleev().get(), args.length() + 1, construct);
 
     JSObject &callee = args.callee();
-    Class *clasp = callee.getClass();
+    const Class *clasp = callee.getClass();
 
     /* Invoke non-functions. */
     if (JS_UNLIKELY(clasp != &JSFunction::class_)) {
 #if JS_HAS_NO_SUCH_METHOD
         if (JS_UNLIKELY(clasp == &js_NoSuchMethodClass))
             return NoSuchMethod(cx, args.length(), args.base());
 #endif
         JS_ASSERT_IF(construct, !clasp->construct);
@@ -556,17 +556,17 @@ js::InvokeConstructor(JSContext *cx, Cal
 
         if (!Invoke(cx, args, CONSTRUCT))
             return false;
 
         JS_ASSERT(args.rval().isObject());
         return true;
     }
 
-    Class *clasp = callee.getClass();
+    const Class *clasp = callee.getClass();
     if (!clasp->construct)
         return ReportIsNotFunction(cx, args.calleev().get(), args.length() + 1, CONSTRUCT);
 
     return CallJSNativeConstructor(cx, clasp->construct, args);
 }
 
 bool
 js::InvokeConstructor(JSContext *cx, Value fval, unsigned argc, Value *argv, Value *rval)
@@ -654,17 +654,17 @@ js::Execute(JSContext *cx, HandleScript 
 
     return ExecuteKernel(cx, script, *scopeChain, thisv, EXECUTE_GLOBAL,
                          NullFramePtr() /* evalInFrame */, rval);
 }
 
 bool
 js::HasInstance(JSContext *cx, HandleObject obj, HandleValue v, bool *bp)
 {
-    Class *clasp = obj->getClass();
+    const Class *clasp = obj->getClass();
     RootedValue local(cx, v);
     if (clasp->hasInstance)
         return clasp->hasInstance(cx, obj, &local, bp);
 
     RootedValue val(cx, ObjectValue(*obj));
     js_ReportValueError(cx, JSMSG_BAD_INSTANCEOF_RHS,
                         JSDVG_SEARCH_STACK, val, NullPtr());
     return false;
--- a/js/src/vm/NumberObject.h
+++ b/js/src/vm/NumberObject.h
@@ -14,17 +14,17 @@ namespace js {
 class NumberObject : public JSObject
 {
     /* Stores this Number object's [[PrimitiveValue]]. */
     static const unsigned PRIMITIVE_VALUE_SLOT = 0;
 
   public:
     static const unsigned RESERVED_SLOTS = 1;
 
-    static Class class_;
+    static const Class class_;
 
     /*
      * Creates a new Number object boxing the given number.  The object's
      * [[Prototype]] is determined from context.
      */
     static inline NumberObject *create(JSContext *cx, double d);
 
     double unbox() const {
--- a/js/src/vm/ObjectImpl.cpp
+++ b/js/src/vm/ObjectImpl.cpp
@@ -333,17 +333,17 @@ js::ObjectImpl::nativeLookupPure(jsid id
 
 void
 js::ObjectImpl::markChildren(JSTracer *trc)
 {
     MarkTypeObject(trc, &type_, "type");
 
     MarkShape(trc, &shape_, "shape");
 
-    Class *clasp = type_->clasp;
+    const Class *clasp = type_->clasp;
     JSObject *obj = asObjectPtr();
     if (clasp->trace)
         clasp->trace(trc, obj);
 
     if (shape_->isNative()) {
         MarkObjectSlots(trc, obj, 0, obj->slotSpan());
         gc::MarkArraySlots(trc, obj->getDenseInitializedLength(), obj->getDenseElements(), "objectElements");
     }
@@ -560,17 +560,17 @@ js::GetOwnProperty(JSContext *cx, Handle
     Rooted<PropertyId> pid(cx, pid_);
 
     if (Downcast(obj)->is<ProxyObject>())
         MOZ_ASSUME_UNREACHABLE("NYI: proxy [[GetOwnProperty]]");
 
     RootedShape shape(cx, obj->nativeLookup(cx, pid));
     if (!shape) {
         /* Not found: attempt to resolve it. */
-        Class *clasp = obj->getClass();
+        const Class *clasp = obj->getClass();
         JSResolveOp resolve = clasp->resolve;
         if (resolve != JS_ResolveStub) {
             Rooted<jsid> id(cx, pid.get().asId());
             Rooted<JSObject*> robj(cx, static_cast<JSObject*>(obj.get()));
             if (clasp->flags & JSCLASS_NEW_RESOLVE) {
                 Rooted<JSObject*> obj2(cx, NULL);
                 JSNewResolveOp op = reinterpret_cast<JSNewResolveOp>(resolve);
                 if (!op(cx, robj, id, resolveFlags, &obj2))
--- a/js/src/vm/ObjectImpl.h
+++ b/js/src/vm/ObjectImpl.h
@@ -964,17 +964,17 @@ class ObjectImpl : public gc::Cell
 
     /* These functions are public, and they should remain public. */
 
   public:
     JSObject * getProto() const {
         return type_->proto;
     }
 
-    Class *getClass() const {
+    const Class *getClass() const {
         return type_->clasp;
     }
 
     static inline bool
     isExtensible(ExclusiveContext *cx, Handle<ObjectImpl*> obj, bool *extensible);
 
     // Indicates whether a non-proxy is extensible.  Don't call on proxies!
     // This method really shouldn't exist -- but there are a few internal
@@ -1245,17 +1245,17 @@ class ObjectImpl : public gc::Cell
     }
     bool nativeContainsPure(PropertyName* name) {
         return nativeContainsPure(NameToId(name));
     }
     bool nativeContainsPure(Shape* shape) {
         return nativeLookupPure(shape->propid()) == shape;
     }
 
-    JSClass *getJSClass() const {
+    const JSClass *getJSClass() const {
         return Jsvalify(getClass());
     }
     bool hasClass(const Class *c) const {
         return getClass() == c;
     }
     const ObjectOps *getOps() const {
         return &getClass()->ops;
     }
--- a/js/src/vm/OldDebugAPI.cpp
+++ b/js/src/vm/OldDebugAPI.cpp
@@ -700,17 +700,17 @@ JS_GetPropertyDescArray(JSContext *cx, J
                 goto bad;
         }
 
         pda->length = props.length();
         pda->array = pd;
         return true;
     }
 
-    Class *clasp;
+    const Class *clasp;
     clasp = obj->getClass();
     if (!obj->isNative() || (clasp->flags & JSCLASS_NEW_ENUMERATE)) {
         JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
                              JSMSG_CANT_DESCRIBE_PROPS, clasp->name);
         return false;
     }
     if (!clasp->enumerate(cx, obj))
         return false;
--- a/js/src/vm/Probes.h
+++ b/js/src/vm/Probes.h
@@ -124,17 +124,17 @@ void DTraceEnterJSFun(JSContext *cx, JSF
 void DTraceExitJSFun(JSContext *cx, JSFunction *fun, JSScript *script);
 
 } /* namespace Probes */
 
 #ifdef INCLUDE_MOZILLA_DTRACE
 static const char *ObjectClassname(JSObject *obj) {
     if (!obj)
         return "(null object)";
-    Class *clasp = obj->getClass();
+    const Class *clasp = obj->getClass();
     if (!clasp)
         return "(null)";
     const char *class_name = clasp->name;
     if (!class_name)
         return "(null class name)";
     return class_name;
 }
 #endif
@@ -154,17 +154,17 @@ Probes::createObject(ExclusiveContext *c
 
 inline bool
 Probes::finalizeObject(JSObject *obj)
 {
     bool ok = true;
 
 #ifdef INCLUDE_MOZILLA_DTRACE
     if (JAVASCRIPT_OBJECT_FINALIZE_ENABLED()) {
-        Class *clasp = obj->getClass();
+        const Class *clasp = obj->getClass();
 
         /* the first arg is NULL - reserved for future use (filename?) */
         JAVASCRIPT_OBJECT_FINALIZE(NULL, (char *)clasp->name, (uintptr_t)obj);
     }
 #endif
 
     return ok;
 }
--- a/js/src/vm/ProxyObject.h
+++ b/js/src/vm/ProxyObject.h
@@ -81,40 +81,40 @@ class ProxyObject : public JSObject
 };
 
 class FunctionProxyObject : public ProxyObject
 {
     static const uint32_t CALL_SLOT      = 4;
     static const uint32_t CONSTRUCT_SLOT = 5;
 
   public:
-    static Class class_;
+    static const Class class_;
 
     static FunctionProxyObject *New(JSContext *cx, BaseProxyHandler *handler, HandleValue priv,
                                     JSObject *proto, JSObject *parent, JSObject *call,
                                     JSObject *construct);
 
     HeapSlot &call() { return getSlotRef(CALL_SLOT); }
 
     inline HeapSlot &construct();
     inline Value constructOrUndefined() const;
 
     void nukeExtra();
 };
 
 class ObjectProxyObject : public ProxyObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 };
 
 class OuterWindowProxyObject : public ObjectProxyObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 };
 
 } // namespace js
 
 // Note: the following |JSObject::is<T>| methods are implemented in terms of
 // the Is*Proxy() friend API functions to ensure the implementations are tied
 // together.  The exception is |JSObject::is<js::OuterWindowProxyObject>()
 // const|, which uses the standard template definition, because there is no
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -204,17 +204,17 @@ regexp_trace(JSTracer *trc, JSObject *ob
       * We have to check both conditions, since:
       *   1. During TraceRuntime, isHeapBusy() is true
       *   2. When a write barrier executes, IS_GC_MARKING_TRACER is true.
       */
     if (trc->runtime->isHeapBusy() && IS_GC_MARKING_TRACER(trc))
         obj->setPrivate(NULL);
 }
 
-Class RegExpObject::class_ = {
+const Class RegExpObject::class_ = {
     js_RegExp_str,
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(RegExpObject::RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_RegExp),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
--- a/js/src/vm/RegExpObject.h
+++ b/js/src/vm/RegExpObject.h
@@ -338,17 +338,17 @@ class RegExpObject : public JSObject
     static const unsigned GLOBAL_FLAG_SLOT         = 2;
     static const unsigned IGNORE_CASE_FLAG_SLOT    = 3;
     static const unsigned MULTILINE_FLAG_SLOT      = 4;
     static const unsigned STICKY_FLAG_SLOT         = 5;
 
   public:
     static const unsigned RESERVED_SLOTS = 6;
 
-    static Class class_;
+    static const Class class_;
 
     /*
      * Note: The regexp statics flags are OR'd into the provided flags,
      * so this function is really meant for object creation during code
      * execution, as opposed to during something like XDR.
      */
     static RegExpObject *
     create(ExclusiveContext *cx, RegExpStatics *res, const jschar *chars, size_t length,
--- a/js/src/vm/RegExpStatics.cpp
+++ b/js/src/vm/RegExpStatics.cpp
@@ -30,17 +30,17 @@ static void
 resc_trace(JSTracer *trc, JSObject *obj)
 {
     void *pdata = obj->getPrivate();
     JS_ASSERT(pdata);
     RegExpStatics *res = static_cast<RegExpStatics *>(pdata);
     res->mark(trc);
 }
 
-Class RegExpStaticsObject::class_ = {
+const Class RegExpStaticsObject::class_ = {
     "RegExpStatics",
     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS,
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/src/vm/RegExpStaticsObject.h
+++ b/js/src/vm/RegExpStaticsObject.h
@@ -9,17 +9,17 @@
 
 #include "jsobj.h"
 
 namespace js {
 
 class RegExpStaticsObject : public JSObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 
     size_t sizeOfData(mozilla::MallocSizeOf mallocSizeOf) {
         return mallocSizeOf(getPrivate());
     }
 };
 
 } // namespace js
 
--- a/js/src/vm/Runtime-inl.h
+++ b/js/src/vm/Runtime-inl.h
@@ -15,30 +15,30 @@
 #include "jit/IonFrames.h"
 #include "vm/Probes.h"
 
 #include "jsgcinlines.h"
 
 namespace js {
 
 inline bool
-NewObjectCache::lookupProto(Class *clasp, JSObject *proto, gc::AllocKind kind, EntryIndex *pentry)
+NewObjectCache::lookupProto(const Class *clasp, JSObject *proto, gc::AllocKind kind, EntryIndex *pentry)
 {
     JS_ASSERT(!proto->is<GlobalObject>());
     return lookup(clasp, proto, kind, pentry);
 }
 
 inline bool
-NewObjectCache::lookupGlobal(Class *clasp, js::GlobalObject *global, gc::AllocKind kind, EntryIndex *pentry)
+NewObjectCache::lookupGlobal(const Class *clasp, js::GlobalObject *global, gc::AllocKind kind, EntryIndex *pentry)
 {
     return lookup(clasp, global, kind, pentry);
 }
 
 inline void
-NewObjectCache::fillGlobal(EntryIndex entry, Class *clasp, js::GlobalObject *global, gc::AllocKind kind, JSObject *obj)
+NewObjectCache::fillGlobal(EntryIndex entry, const Class *clasp, js::GlobalObject *global, gc::AllocKind kind, JSObject *obj)
 {
     //JS_ASSERT(global == obj->getGlobal());
     return fill(entry, clasp, global, kind, obj);
 }
 
 inline JSObject *
 NewObjectCache::newObjectFromHit(JSContext *cx, EntryIndex entry_, js::gc::InitialHeap heap)
 {
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -277,17 +277,17 @@ class NewObjectCache
     static void staticAsserts() {
         JS_STATIC_ASSERT(NewObjectCache::MAX_OBJ_SIZE == sizeof(JSObject_Slots16));
         JS_STATIC_ASSERT(gc::FINALIZE_OBJECT_LAST == gc::FINALIZE_OBJECT16_BACKGROUND);
     }
 
     struct Entry
     {
         /* Class of the constructed object. */
-        Class *clasp;
+        const Class *clasp;
 
         /*
          * Key with one of three possible values:
          *
          * - Global for the object. The object must have a standard class for
          *   which the global's prototype can be determined, and the object's
          *   parent will be the global.
          *
@@ -323,61 +323,61 @@ class NewObjectCache
 
     /* Remove any cached items keyed on moved objects. */
     void clearNurseryObjects(JSRuntime *rt);
 
     /*
      * Get the entry index for the given lookup, return whether there was a hit
      * on an existing entry.
      */
-    inline bool lookupProto(Class *clasp, JSObject *proto, gc::AllocKind kind, EntryIndex *pentry);
-    inline bool lookupGlobal(Class *clasp, js::GlobalObject *global, gc::AllocKind kind,
+    inline bool lookupProto(const Class *clasp, JSObject *proto, gc::AllocKind kind, EntryIndex *pentry);
+    inline bool lookupGlobal(const Class *clasp, js::GlobalObject *global, gc::AllocKind kind,
                              EntryIndex *pentry);
 
-    bool lookupType(Class *clasp, js::types::TypeObject *type, gc::AllocKind kind,
+    bool lookupType(const Class *clasp, js::types::TypeObject *type, gc::AllocKind kind,
                     EntryIndex *pentry)
     {
         return lookup(clasp, type, kind, pentry);
     }
 
     /*
      * Return a new object from a cache hit produced by a lookup method, or
      * NULL if returning the object could possibly trigger GC (does not
      * indicate failure).
      */
     inline JSObject *newObjectFromHit(JSContext *cx, EntryIndex entry, js::gc::InitialHeap heap);
 
     /* Fill an entry after a cache miss. */
-    void fillProto(EntryIndex entry, Class *clasp, js::TaggedProto proto, gc::AllocKind kind, JSObject *obj);
+    void fillProto(EntryIndex entry, const Class *clasp, js::TaggedProto proto, gc::AllocKind kind, JSObject *obj);
 
-    inline void fillGlobal(EntryIndex entry, Class *clasp, js::GlobalObject *global,
+    inline void fillGlobal(EntryIndex entry, const Class *clasp, js::GlobalObject *global,
                            gc::AllocKind kind, JSObject *obj);
 
-    void fillType(EntryIndex entry, Class *clasp, js::types::TypeObject *type, gc::AllocKind kind,
+    void fillType(EntryIndex entry, const Class *clasp, js::types::TypeObject *type, gc::AllocKind kind,
                   JSObject *obj)
     {
         JS_ASSERT(obj->type() == type);
         return fill(entry, clasp, type, kind, obj);
     }
 
     /* Invalidate any entries which might produce an object with shape/proto. */
     void invalidateEntriesForShape(JSContext *cx, HandleShape shape, HandleObject proto);
 
   private:
-    bool lookup(Class *clasp, gc::Cell *key, gc::AllocKind kind, EntryIndex *pentry) {
+    bool lookup(const Class *clasp, gc::Cell *key, gc::AllocKind kind, EntryIndex *pentry) {
         uintptr_t hash = (uintptr_t(clasp) ^ uintptr_t(key)) + kind;
         *pentry = hash % mozilla::ArrayLength(entries);
 
         Entry *entry = &entries[*pentry];
 
         /* N.B. Lookups with the same clasp/key but different kinds map to different entries. */
         return (entry->clasp == clasp && entry->key == key);
     }
 
-    void fill(EntryIndex entry_, Class *clasp, gc::Cell *key, gc::AllocKind kind, JSObject *obj) {
+    void fill(EntryIndex entry_, const Class *clasp, gc::Cell *key, gc::AllocKind kind, JSObject *obj) {
         JS_ASSERT(unsigned(entry_) < mozilla::ArrayLength(entries));
         Entry *entry = &entries[entry_];
 
         JS_ASSERT(!obj->hasDynamicSlots() && !obj->hasDynamicElements());
 
         entry->clasp = clasp;
         entry->key = key;
         entry->kind = kind;
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -303,29 +303,29 @@ CallObject::createForStrictEval(JSContex
     JS_ASSERT_IF(frame.isStackFrame(), cx->interpreterRegs().pc == frame.script()->code);
 
     RootedFunction callee(cx);
     RootedScript script(cx, frame.script());
     RootedObject scopeChain(cx, frame.scopeChain());
     return create(cx, script, scopeChain, callee);
 }
 
-Class CallObject::class_ = {
+const Class CallObject::class_ = {
     "Call",
     JSCLASS_IS_ANONYMOUS | JSCLASS_HAS_RESERVED_SLOTS(CallObject::RESERVED_SLOTS),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
     NULL                     /* convert: Leave it NULL so we notice if calls ever escape */
 };
 
-Class DeclEnvObject::class_ = {
+const Class DeclEnvObject::class_ = {
     js_Object_str,
     JSCLASS_HAS_RESERVED_SLOTS(DeclEnvObject::RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Object),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
@@ -355,17 +355,17 @@ DeclEnvObject::createTemplateObject(JSCo
         return NULL;
 
     RootedObject obj(cx, JSObject::create(cx, FINALIZE_KIND, heap, emptyDeclEnvShape, type));
     if (!obj)
         return NULL;
 
     // Assign a fixed slot to a property with the same name as the lambda.
     Rooted<jsid> id(cx, AtomToId(fun->atom()));
-    Class *clasp = obj->getClass();
+    const Class *clasp = obj->getClass();
     unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY;
     if (!JSObject::putProperty(cx, obj, id, clasp->getProperty, clasp->setProperty,
                                lambdaSlot(), attrs, 0, 0))
     {
         return NULL;
     }
 
     JS_ASSERT(!obj->hasDynamicSlots());
@@ -559,17 +559,17 @@ with_Enumerate(JSContext *cx, HandleObje
 }
 
 static JSObject *
 with_ThisObject(JSContext *cx, HandleObject obj)
 {
     return &obj->as<WithObject>().withThis();
 }
 
-Class WithObject::class_ = {
+const Class WithObject::class_ = {
     "With",
     JSCLASS_HAS_RESERVED_SLOTS(WithObject::RESERVED_SLOTS) |
     JSCLASS_IS_ANONYMOUS,
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
@@ -710,17 +710,17 @@ StaticBlockObject::addVar(ExclusiveConte
      */
     uint32_t slot = JSSLOT_FREE(&BlockObject::class_) + index;
     return JSObject::addPropertyInternal(cx, block, id, /* getter = */ NULL, /* setter = */ NULL,
                                          slot, JSPROP_ENUMERATE | JSPROP_PERMANENT,
                                          Shape::HAS_SHORTID, index, spp,
                                          /* allowDictionary = */ false);
 }
 
-Class BlockObject::class_ = {
+const Class BlockObject::class_ = {
     "Block",
     JSCLASS_IMPLEMENTS_BARRIERS |
     JSCLASS_HAS_RESERVED_SLOTS(BlockObject::RESERVED_SLOTS) |
     JSCLASS_IS_ANONYMOUS,
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
--- a/js/src/vm/ScopeObject.h
+++ b/js/src/vm/ScopeObject.h
@@ -196,17 +196,17 @@ class ScopeObject : public JSObject
 class CallObject : public ScopeObject
 {
     static const uint32_t CALLEE_SLOT = 1;
 
     static CallObject *
     create(JSContext *cx, HandleScript script, HandleObject enclosing, HandleFunction callee);
 
   public:
-    static Class class_;
+    static const Class class_;
 
     /* These functions are internal and are exposed only for JITs. */
     static CallObject *
     create(JSContext *cx, HandleScript script, HandleShape shape, HandleTypeObject type, HeapSlot *slots);
 
     static CallObject *
     createTemplateObject(JSContext *cx, HandleScript script, gc::InitialHeap heap);
 
@@ -254,17 +254,17 @@ class DeclEnvObject : public ScopeObject
 {
     // Pre-allocated slot for the named lambda.
     static const uint32_t LAMBDA_SLOT = 1;
 
   public:
     static const uint32_t RESERVED_SLOTS = 2;
     static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT2_BACKGROUND;
 
-    static Class class_;
+    static const Class class_;
 
     static DeclEnvObject *
     createTemplateObject(JSContext *cx, HandleFunction fun, gc::InitialHeap heap);
 
     static DeclEnvObject *create(JSContext *cx, HandleObject enclosing, HandleFunction callee);
 
     static inline size_t lambdaSlot() {
         return LAMBDA_SLOT;
@@ -289,17 +289,17 @@ class WithObject : public NestedScopeObj
 
     /* Use WithObject::object() instead. */
     JSObject *getProto() const;
 
   public:
     static const unsigned RESERVED_SLOTS = 3;
     static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT4_BACKGROUND;
 
-    static Class class_;
+    static const Class class_;
 
     static WithObject *
     create(JSContext *cx, HandleObject proto, HandleObject enclosing, uint32_t depth);
 
     /* Return object for the 'this' class hook. */
     JSObject &withThis() const {
         return getReservedSlot(THIS_SLOT).toObject();
     }
@@ -311,17 +311,17 @@ class WithObject : public NestedScopeObj
 };
 
 class BlockObject : public NestedScopeObject
 {
   public:
     static const unsigned RESERVED_SLOTS = 2;
     static const gc::AllocKind FINALIZE_KIND = gc::FINALIZE_OBJECT4_BACKGROUND;
 
-    static Class class_;
+    static const Class class_;
 
     /* Return the number of variables associated with this block. */
     uint32_t slotCount() const {
         return propertyCount();
     }
 
     /*
      * Return the local corresponding to the ith binding where i is in the
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -42,17 +42,17 @@ struct SelfHostedClass
     Class class_;
 
     /*
      * Create a new self-hosted proto with its class set to a new dynamically
      * allocated class with numSlots reserved slots.
      */
     static JSObject *newPrototype(JSContext *cx, uint32_t numSlots);
 
-    static bool is(JSContext *cx, Class *clasp);
+    static bool is(JSContext *cx, const Class *clasp);
 
     SelfHostedClass(const char *name, uint32_t numSlots);
 };
 
 } /* namespace js */
 
 JSObject *
 SelfHostedClass::newPrototype(JSContext *cx, uint32_t numSlots)
@@ -67,17 +67,17 @@ SelfHostedClass::newPrototype(JSContext 
     RootedObject proto(cx, global->createBlankPrototype(cx, &shClass->class_));
     if (!proto)
         return NULL;
 
     return proto;
 }
 
 bool
-SelfHostedClass::is(JSContext *cx, Class *clasp)
+SelfHostedClass::is(JSContext *cx, const Class *clasp)
 {
     SelfHostedClass *shClass = cx->runtime()->selfHostedClasses();
     while (shClass) {
         if (clasp == &shClass->class_)
             return true;
         shClass = shClass->next;
     }
     return false;
@@ -99,17 +99,17 @@ SelfHostedClass::SelfHostedClass(const c
 }
 
 static void
 selfHosting_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
 {
     PrintError(cx, stderr, message, report, true);
 }
 
-static JSClass self_hosting_global_class = {
+static const JSClass self_hosting_global_class = {
     "self-hosting-global", JSCLASS_GLOBAL_FLAGS,
     JS_PropertyStub,  JS_DeletePropertyStub,
     JS_PropertyStub,  JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub,
     JS_ConvertStub,   NULL
 };
 
 bool
--- a/js/src/vm/Shape-inl.h
+++ b/js/src/vm/Shape-inl.h
@@ -35,30 +35,30 @@ static inline void
 GetterSetterWriteBarrierPostRemove(JSRuntime *rt, JSObject **objp)
 {
 #ifdef JSGC_GENERATIONAL
     rt->gcStoreBuffer.removeRelocatableCell(reinterpret_cast<gc::Cell **>(objp));
 #endif
 }
 
 inline
-BaseShape::BaseShape(JSCompartment *comp, Class *clasp, JSObject *parent, JSObject *metadata,
+BaseShape::BaseShape(JSCompartment *comp, const Class *clasp, JSObject *parent, JSObject *metadata,
                      uint32_t objectFlags)
 {
     JS_ASSERT(!(objectFlags & ~OBJECT_FLAG_MASK));
     mozilla::PodZero(this);
     this->clasp = clasp;
     this->parent = parent;
     this->metadata = metadata;
     this->flags = objectFlags;
     this->compartment_ = comp;
 }
 
 inline
-BaseShape::BaseShape(JSCompartment *comp, Class *clasp, JSObject *parent, JSObject *metadata,
+BaseShape::BaseShape(JSCompartment *comp, const Class *clasp, JSObject *parent, JSObject *metadata,
                      uint32_t objectFlags, uint8_t attrs,
                      PropertyOp rawGetter, StrictPropertyOp rawSetter)
 {
     JS_ASSERT(!(objectFlags & ~OBJECT_FLAG_MASK));
     mozilla::PodZero(this);
     this->clasp = clasp;
     this->parent = parent;
     this->metadata = metadata;
@@ -117,17 +117,17 @@ BaseShape::operator=(const BaseShape &ot
             GetterSetterWriteBarrierPostRemove(runtimeFromMainThread(), &setterObj);
         rawSetter = other.rawSetter;
     }
     compartment_ = other.compartment_;
     return *this;
 }
 
 inline
-StackBaseShape::StackBaseShape(ExclusiveContext *cx, Class *clasp,
+StackBaseShape::StackBaseShape(ExclusiveContext *cx, const Class *clasp,
                                JSObject *parent, JSObject *metadata, uint32_t objectFlags)
   : flags(objectFlags),
     clasp(clasp),
     parent(parent),
     metadata(metadata),
     rawGetter(NULL),
     rawSetter(NULL),
     compartment(cx->compartment_)
--- a/js/src/vm/Shape.cpp
+++ b/js/src/vm/Shape.cpp
@@ -1327,17 +1327,17 @@ InitialShapeEntry::match(const InitialSh
         && lookup.proto.toWord() == key.proto.toWord()
         && lookup.parent == shape->getObjectParent()
         && lookup.metadata == shape->getObjectMetadata()
         && lookup.nfixed == shape->numFixedSlots()
         && lookup.baseFlags == shape->getObjectFlags();
 }
 
 /* static */ Shape *
-EmptyShape::getInitialShape(ExclusiveContext *cx, Class *clasp, TaggedProto proto,
+EmptyShape::getInitialShape(ExclusiveContext *cx, const Class *clasp, TaggedProto proto,
                             JSObject *parent, JSObject *metadata,
                             size_t nfixed, uint32_t objectFlags)
 {
     JS_ASSERT_IF(proto.isObject(), cx->isInsideCurrentCompartment(proto.toObject()));
     JS_ASSERT_IF(parent, cx->isInsideCurrentCompartment(parent));
 
     InitialShapeSet &table = cx->compartment()->initialShapes;
 
@@ -1371,27 +1371,27 @@ EmptyShape::getInitialShape(ExclusiveCon
     {
         return NULL;
     }
 
     return shape;
 }
 
 /* static */ Shape *
-EmptyShape::getInitialShape(ExclusiveContext *cx, Class *clasp, TaggedProto proto,
+EmptyShape::getInitialShape(ExclusiveContext *cx, const Class *clasp, TaggedProto proto,
                             JSObject *parent, JSObject *metadata,
                             AllocKind kind, uint32_t objectFlags)
 {
     return getInitialShape(cx, clasp, proto, parent, metadata, GetGCKindSlots(kind, clasp), objectFlags);
 }
 
 void
 NewObjectCache::invalidateEntriesForShape(JSContext *cx, HandleShape shape, HandleObject proto)
 {
-    Class *clasp = shape->getObjectClass();
+    const Class *clasp = shape->getObjectClass();
 
     gc::AllocKind kind = gc::GetGCObjectKind(shape->numFixedSlots());
     if (CanBeFinalizedInBackground(kind, clasp))
         kind = GetBackgroundAllocKind(kind);
 
     Rooted<GlobalObject *> global(cx, &shape->getObjectParent()->global());
     Rooted<types::TypeObject *> type(cx, cx->getNewType(clasp, proto.get()));
 
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -554,17 +554,17 @@ class BaseShape : public js::gc::Cell
         NEW_TYPE_UNKNOWN    =  0x400,
         UNCACHEABLE_PROTO   =  0x800,
         HAD_ELEMENTS_ACCESS = 0x1000,
 
         OBJECT_FLAG_MASK    = 0x1ff8
     };
 
   private:
-    Class               *clasp;         /* Class of referring object. */
+    const Class         *clasp;         /* Class of referring object. */
     HeapPtrObject       parent;         /* Parent of referring object. */
     HeapPtrObject       metadata;       /* Optional holder of metadata about
                                          * the referring object. */
     JSCompartment       *compartment_;  /* Compartment shape belongs to. */
     uint32_t            flags;          /* Vector of above flags. */
     uint32_t            slotSpan_;      /* Object slot span for BaseShapes at
                                          * dictionary last properties. */
 
@@ -586,19 +586,19 @@ class BaseShape : public js::gc::Cell
     /* For owned BaseShapes, the shape's shape table. */
     ShapeTable       *table_;
 
     BaseShape(const BaseShape &base) MOZ_DELETE;
 
   public:
     void finalize(FreeOp *fop);
 
-    inline BaseShape(JSCompartment *comp, Class *clasp, JSObject *parent, JSObject *metadata,
+    inline BaseShape(JSCompartment *comp, const Class *clasp, JSObject *parent, JSObject *metadata,
                      uint32_t objectFlags);
-    inline BaseShape(JSCompartment *comp, Class *clasp, JSObject *parent, JSObject *metadata,
+    inline BaseShape(JSCompartment *comp, const Class *clasp, JSObject *parent, JSObject *metadata,
                      uint32_t objectFlags, uint8_t attrs,
                      PropertyOp rawGetter, StrictPropertyOp rawSetter);
     inline BaseShape(const StackBaseShape &base);
 
     /* Not defined: BaseShapes must not be stack allocated. */
     ~BaseShape();
 
     inline BaseShape &operator=(const BaseShape &other);
@@ -710,34 +710,34 @@ BaseShape::baseUnowned()
 }
 
 /* Entries for the per-compartment baseShapes set of unowned base shapes. */
 struct StackBaseShape
 {
     typedef const StackBaseShape *Lookup;
 
     uint32_t flags;
-    Class *clasp;
+    const Class *clasp;
     JSObject *parent;
     JSObject *metadata;
     PropertyOp rawGetter;
     StrictPropertyOp rawSetter;
     JSCompartment *compartment;
 
     explicit StackBaseShape(BaseShape *base)
       : flags(base->flags & BaseShape::OBJECT_FLAG_MASK),
         clasp(base->clasp),
         parent(base->parent),
         metadata(base->metadata),
         rawGetter(NULL),
         rawSetter(NULL),
         compartment(base->compartment())
     {}
 
-    inline StackBaseShape(ExclusiveContext *cx, Class *clasp,
+    inline StackBaseShape(ExclusiveContext *cx, const Class *clasp,
                           JSObject *parent, JSObject *metadata, uint32_t objectFlags);
     inline StackBaseShape(Shape *shape);
 
     void updateGetterSetter(uint8_t attrs, PropertyOp rawGetter, StrictPropertyOp rawSetter) {
         flags &= ~(BaseShape::HAS_GETTER_OBJECT | BaseShape::HAS_SETTER_OBJECT);
         if ((attrs & JSPROP_GETTER) && rawGetter) {
             JS_ASSERT(!IsPoisonedPtr(rawGetter));
             flags |= BaseShape::HAS_GETTER_OBJECT;
@@ -907,17 +907,17 @@ class Shape : public js::gc::Cell
         }
 
         void popFront() {
             JS_ASSERT(!empty());
             cursor = cursor->parent;
         }
     };
 
-    Class *getObjectClass() const { return base()->clasp; }
+    const Class *getObjectClass() const { return base()->clasp; }
     JSObject *getObjectParent() const { return base()->parent; }
     JSObject *getObjectMetadata() const { return base()->metadata; }
 
     static Shape *setObjectParent(ExclusiveContext *cx,
                                   JSObject *obj, TaggedProto proto, Shape *last);
     static Shape *setObjectMetadata(JSContext *cx,
                                     JSObject *metadata, TaggedProto proto, Shape *last);
     static Shape *setObjectFlag(ExclusiveContext *cx,
@@ -1245,20 +1245,20 @@ class AutoRooterGetterSetter
 struct EmptyShape : public js::Shape
 {
     EmptyShape(UnownedBaseShape *base, uint32_t nfixed);
 
     /*
      * Lookup an initial shape matching the given parameters, creating an empty
      * shape if none was found.
      */
-    static Shape *getInitialShape(ExclusiveContext *cx, Class *clasp,
+    static Shape *getInitialShape(ExclusiveContext *cx, const Class *clasp,
                                   TaggedProto proto, JSObject *metadata,
                                   JSObject *parent, size_t nfixed, uint32_t objectFlags = 0);
-    static Shape *getInitialShape(ExclusiveContext *cx, Class *clasp,
+    static Shape *getInitialShape(ExclusiveContext *cx, const Class *clasp,
                                   TaggedProto proto, JSObject *metadata,
                                   JSObject *parent, gc::AllocKind kind, uint32_t objectFlags = 0);
 
     /*
      * Reinsert an alternate initial shape, to be returned by future
      * getInitialShape calls, until the new shape becomes unreachable in a GC
      * and the table entry is purged.
      */
@@ -1281,23 +1281,23 @@ struct InitialShapeEntry
     /*
      * Matching prototype for the entry. The shape of an object determines its
      * prototype, but the prototype cannot be determined from the shape itself.
      */
     TaggedProto proto;
 
     /* State used to determine a match on an initial shape. */
     struct Lookup {
-        Class *clasp;
+        const Class *clasp;
         TaggedProto proto;
         JSObject *parent;
         JSObject *metadata;
         uint32_t nfixed;
         uint32_t baseFlags;
-        Lookup(Class *clasp, TaggedProto proto, JSObject *parent, JSObject *metadata,
+        Lookup(const Class *clasp, TaggedProto proto, JSObject *parent, JSObject *metadata,
                uint32_t nfixed, uint32_t baseFlags)
           : clasp(clasp), proto(proto), parent(parent), metadata(metadata),
             nfixed(nfixed), baseFlags(baseFlags)
         {}
     };
 
     inline InitialShapeEntry();
     inline InitialShapeEntry(const ReadBarriered<Shape> &shape, TaggedProto proto);
--- a/js/src/vm/StopIterationObject.h
+++ b/js/src/vm/StopIterationObject.h
@@ -9,14 +9,14 @@
 
 #include "jsobj.h"
 
 namespace js {
 
 class StopIterationObject : public JSObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 };
 
 } // namespace js
 
 #endif /* vm_StopIterationObject_h */
--- a/js/src/vm/StringObject.h
+++ b/js/src/vm/StringObject.h
@@ -15,17 +15,17 @@ namespace js {
 class StringObject : public JSObject
 {
     static const unsigned PRIMITIVE_VALUE_SLOT = 0;
     static const unsigned LENGTH_SLOT = 1;
 
   public:
     static const unsigned RESERVED_SLOTS = 2;
 
-    static Class class_;
+    static const Class class_;
 
     /*
      * Creates a new String object boxing the given string.  The object's
      * [[Prototype]] is determined from context.
      */
     static inline StringObject *create(JSContext *cx, HandleString str,
                                        NewObjectKind newKind = GenericObject);
 
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -1331,22 +1331,22 @@ class TypedArrayObjectTemplate : public 
     typedef TypedArrayObjectTemplate<NativeType> ThisTypedArrayObject;
     static const int ArrayTypeID() { return TypeIDOfType<NativeType>(); }
     static const bool ArrayTypeIsUnsigned() { return TypeIsUnsigned<NativeType>(); }
     static const bool ArrayTypeIsFloatingPoint() { return TypeIsFloatingPoint<NativeType>(); }
     static const bool ArrayElementTypeMayBeDouble() { return ElementTypeMayBeDouble<NativeType>(); }
 
     static const size_t BYTES_PER_ELEMENT = sizeof(ThisType);
 
-    static inline Class *protoClass()
+    static inline const Class *protoClass()
     {
         return &TypedArrayObject::protoClasses[ArrayTypeID()];
     }
 
-    static inline Class *fastClass()
+    static inline const Class *fastClass()
     {
         return &TypedArrayObject::classes[ArrayTypeID()];
     }
 
     static bool is(HandleValue v) {
         return v.isObject() && v.toObject().hasClass(fastClass());
     }
 
@@ -3333,31 +3333,31 @@ TypedArrayObject::copyTypedArrayElement(
 /***
  *** JS impl
  ***/
 
 /*
  * ArrayBufferObject (base)
  */
 
-Class ArrayBufferObject::protoClass = {
+const Class ArrayBufferObject::protoClass = {
     "ArrayBufferPrototype",
     JSCLASS_HAS_PRIVATE |
     JSCLASS_HAS_RESERVED_SLOTS(ARRAYBUFFER_RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_ArrayBuffer),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub
 };
 
-Class ArrayBufferObject::class_ = {
+const Class ArrayBufferObject::class_ = {
     "ArrayBuffer",
     JSCLASS_HAS_PRIVATE |
     JSCLASS_IMPLEMENTS_BARRIERS |
     Class::NON_NATIVE |
     JSCLASS_HAS_RESERVED_SLOTS(ARRAYBUFFER_RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_ArrayBuffer),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
@@ -3446,17 +3446,17 @@ const JSFunctionSpec _typedArray##Object
       Rooted<JSObject*> proto(cx, NULL);                                                     \
       return TypedArrayObjectTemplate<NativeType>::fromBuffer(cx, arrayBuffer, byteOffset,   \
                                                               length, proto);                \
   }                                                                                          \
   JS_FRIEND_API(bool) JS_Is ## Name ## Array(JSObject *obj)                                  \
   {                                                                                          \
       if (!(obj = CheckedUnwrap(obj)))                                                       \
           return false;                                                                      \
-      Class *clasp = obj->getClass();                                                        \
+      const Class *clasp = obj->getClass();                                                  \
       return (clasp == &TypedArrayObject::classes[TypedArrayObjectTemplate<NativeType>::ArrayTypeID()]); \
   }
 
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Int8, int8_t)
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint8, uint8_t)
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint8Clamped, uint8_clamped)
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Int16, int16_t)
 IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Uint16, uint16_t)
@@ -3468,17 +3468,17 @@ IMPL_TYPED_ARRAY_JSAPI_CONSTRUCTORS(Floa
 #define IMPL_TYPED_ARRAY_COMBINED_UNWRAPPERS(Name, ExternalType, InternalType)              \
   JS_FRIEND_API(JSObject *) JS_GetObjectAs ## Name ## Array(JSObject *obj,                  \
                                                             uint32_t *length,               \
                                                             ExternalType **data)            \
   {                                                                                         \
       if (!(obj = CheckedUnwrap(obj)))                                                      \
           return NULL;                                                                      \
                                                                                             \
-      Class *clasp = obj->getClass();                                                       \
+      const Class *clasp = obj->getClass();                                                 \
       if (clasp != &TypedArrayObject::classes[TypedArrayObjectTemplate<InternalType>::ArrayTypeID()]) \
           return NULL;                                                                      \
                                                                                             \
       TypedArrayObject *tarr = &obj->as<TypedArrayObject>();                                \
       *length = tarr->length();                                                             \
       *data = static_cast<ExternalType *>(tarr->viewData());                                \
                                                                                             \
       return obj;                                                                           \
@@ -3622,29 +3622,29 @@ IMPL_TYPED_ARRAY_STATICS(Uint8Array);
 IMPL_TYPED_ARRAY_STATICS(Int16Array);
 IMPL_TYPED_ARRAY_STATICS(Uint16Array);
 IMPL_TYPED_ARRAY_STATICS(Int32Array);
 IMPL_TYPED_ARRAY_STATICS(Uint32Array);
 IMPL_TYPED_ARRAY_STATICS(Float32Array);
 IMPL_TYPED_ARRAY_STATICS(Float64Array);
 IMPL_TYPED_ARRAY_STATICS(Uint8ClampedArray);
 
-Class TypedArrayObject::classes[ScalarTypeRepresentation::TYPE_MAX] = {
+const Class TypedArrayObject::classes[ScalarTypeRepresentation::TYPE_MAX] = {
     IMPL_TYPED_ARRAY_FAST_CLASS(Int8Array),
     IMPL_TYPED_ARRAY_FAST_CLASS(Uint8Array),
     IMPL_TYPED_ARRAY_FAST_CLASS(Int16Array),
     IMPL_TYPED_ARRAY_FAST_CLASS(Uint16Array),
     IMPL_TYPED_ARRAY_FAST_CLASS(Int32Array),
     IMPL_TYPED_ARRAY_FAST_CLASS(Uint32Array),
     IMPL_TYPED_ARRAY_FAST_CLASS(Float32Array),
     IMPL_TYPED_ARRAY_FAST_CLASS(Float64Array),
     IMPL_TYPED_ARRAY_FAST_CLASS(Uint8ClampedArray)
 };
 
-Class TypedArrayObject::protoClasses[ScalarTypeRepresentation::TYPE_MAX] = {
+const Class TypedArrayObject::protoClasses[ScalarTypeRepresentation::TYPE_MAX] = {
     IMPL_TYPED_ARRAY_PROTO_CLASS(Int8Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Uint8Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Int16Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Uint16Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Int32Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Uint32Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Float32Array),
     IMPL_TYPED_ARRAY_PROTO_CLASS(Float64Array),
@@ -3700,31 +3700,31 @@ InitArrayBufferClass(JSContext *cx)
         return NULL;
 
     if (!DefineConstructorAndPrototype(cx, global, JSProto_ArrayBuffer, ctor, arrayBufferProto))
         return NULL;
 
     return arrayBufferProto;
 }
 
-Class DataViewObject::protoClass = {
+const Class DataViewObject::protoClass = {
     "DataViewPrototype",
     JSCLASS_HAS_PRIVATE |
     JSCLASS_HAS_RESERVED_SLOTS(DataViewObject::RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_DataView),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
     JS_PropertyStub,         /* getProperty */
     JS_StrictPropertyStub,   /* setProperty */
     JS_EnumerateStub,
     JS_ResolveStub,
     JS_ConvertStub
 };
 
-Class DataViewObject::class_ = {
+const Class DataViewObject::class_ = {
     "DataView",
     JSCLASS_HAS_PRIVATE |
     JSCLASS_IMPLEMENTS_BARRIERS |
     /* Bug 886622: Consider making this Class NON_NATIVE. */
     JSCLASS_HAS_RESERVED_SLOTS(DataViewObject::RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_DataView),
     JS_PropertyStub,         /* addProperty */
     JS_DeletePropertyStub,   /* delProperty */
--- a/js/src/vm/TypedArrayObject.h
+++ b/js/src/vm/TypedArrayObject.h
@@ -47,19 +47,19 @@ class ArrayBufferViewObject;
  * with a size.
  */
 class ArrayBufferObject : public JSObject
 {
     static bool byteLengthGetterImpl(JSContext *cx, CallArgs args);
     static bool fun_slice_impl(JSContext *cx, CallArgs args);
 
   public:
-    static Class class_;
+    static const Class class_;
 
-    static Class protoClass;
+    static const Class protoClass;
     static const JSFunctionSpec jsfuncs[];
 
     static bool byteLengthGetter(JSContext *cx, unsigned argc, Value *vp);
 
     static bool fun_slice(JSContext *cx, unsigned argc, Value *vp);
 
     static bool class_constructor(JSContext *cx, unsigned argc, Value *vp);
 
@@ -263,18 +263,18 @@ class TypedArrayObject : public ArrayBuf
     // Typed array properties stored in slots, beyond those shared by all
     // ArrayBufferViews.
     static const size_t LENGTH_SLOT    = ArrayBufferViewObject::NUM_SLOTS;
     static const size_t TYPE_SLOT      = ArrayBufferViewObject::NUM_SLOTS + 1;
     static const size_t RESERVED_SLOTS = ArrayBufferViewObject::NUM_SLOTS + 2;
     static const size_t DATA_SLOT      = 7; // private slot, based on alloc kind
 
   public:
-    static Class classes[ScalarTypeRepresentation::TYPE_MAX];
-    static Class protoClasses[ScalarTypeRepresentation::TYPE_MAX];
+    static const Class classes[ScalarTypeRepresentation::TYPE_MAX];
+    static const Class protoClasses[ScalarTypeRepresentation::TYPE_MAX];
 
     static bool obj_lookupGeneric(JSContext *cx, HandleObject obj, HandleId id,
                                   MutableHandleObject objp, MutableHandleShape propp);
     static bool obj_lookupProperty(JSContext *cx, HandleObject obj, HandlePropertyName name,
                                    MutableHandleObject objp, MutableHandleShape propp);
     static bool obj_lookupElement(JSContext *cx, HandleObject obj, uint32_t index,
                                   MutableHandleObject objp, MutableHandleShape propp);
     static bool obj_lookupSpecial(JSContext *cx, HandleObject obj, HandleSpecialId sid,
@@ -400,17 +400,17 @@ TypedArrayShift(ArrayBufferView::ViewTyp
 }
 
 class DataViewObject : public ArrayBufferViewObject
 {
     static const size_t RESERVED_SLOTS = ArrayBufferViewObject::NUM_SLOTS;
     static const size_t DATA_SLOT      = 7; // private slot, based on alloc kind
 
   private:
-    static Class protoClass;
+    static const Class protoClass;
 
     static bool is(HandleValue v) {
         return v.isObject() && v.toObject().hasClass(&class_);
     }
 
     template<Value ValueGetter(DataViewObject *view)>
     static bool
     getterImpl(JSContext *cx, CallArgs args);
@@ -419,17 +419,17 @@ class DataViewObject : public ArrayBuffe
     static bool
     getter(JSContext *cx, unsigned argc, Value *vp);
 
     template<Value ValueGetter(DataViewObject *view)>
     static bool
     defineGetter(JSContext *cx, PropertyName *name, HandleObject proto);
 
   public:
-    static Class class_;
+    static const Class class_;
 
     static Value byteOffsetValue(DataViewObject *view) {
         Value v = view->getReservedSlot(BYTEOFFSET_SLOT);
         JS_ASSERT(v.toInt32() >= 0);
         return v;
     }
 
     static Value byteLengthValue(DataViewObject *view) {
--- a/js/src/vm/WeakMapObject.h
+++ b/js/src/vm/WeakMapObject.h
@@ -12,16 +12,16 @@
 
 namespace js {
 
 typedef WeakMap<EncapsulatedPtrObject, RelocatableValue> ObjectValueMap;
 
 class WeakMapObject : public JSObject
 {
   public:
-    static Class class_;
+    static const Class class_;
 
     ObjectValueMap *getMap() { return static_cast<ObjectValueMap*>(getPrivate()); }
 };
 
 } // namespace js
 
 #endif /* vm_WeakMapObject_h */
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -54,17 +54,17 @@
 using namespace mozilla;
 using namespace mozilla::scache;
 using namespace xpc;
 using namespace JS;
 
 // This JSClass exists to trick silly code that expects toString()ing the
 // global in a component scope to return something with "BackstagePass" in it
 // to continue working.
-static JSClass kFakeBackstagePassJSClass =
+static const JSClass kFakeBackstagePassJSClass =
 {
     "FakeBackstagePass",
     0,
     JS_PropertyStub,
     JS_DeletePropertyStub,
     JS_PropertyStub,
     JS_StrictPropertyStub,
     JS_EnumerateStub,
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -887,17 +887,17 @@ static const JSFunctionSpec glob_functio
     JS_FS("btoa",            Btoa,           1,0),
     JS_FS("Blob",            Blob,           2,JSFUN_CONSTRUCTOR),
     JS_FS("File",            File,           2,JSFUN_CONSTRUCTOR),
     JS_FS("setOperationCallback", SetOperationCallback, 1,0),
     JS_FS("simulateActivityCallback", SimulateActivityCallback, 1,0),
     JS_FS_END
 };
 
-JSClass global_class = {
+const JSClass global_class = {
     "global", 0,
     JS_PropertyStub,  JS_DeletePropertyStub,  JS_PropertyStub,  JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   nullptr
 };
 
 static bool
 env_setProperty(JSContext *cx, HandleObject obj, HandleId id, bool strict, MutableHandleValue vp)
 {
@@ -1009,17 +1009,17 @@ env_resolve(JSContext *cx, HandleObject 
                                    NULL, NULL, JSPROP_ENUMERATE)) {
             return false;
         }
         objp.set(obj);
     }
     return true;
 }
 
-static JSClass env_class = {
+static const JSClass env_class = {
     "environment", JSCLASS_HAS_PRIVATE | JSCLASS_NEW_RESOLVE,
     JS_PropertyStub,  JS_DeletePropertyStub,
     JS_PropertyStub,  env_setProperty,
     env_enumerate, (JSResolveOp) env_resolve,
     JS_ConvertStub,   nullptr
 };
 
 /***************************************************************************/
@@ -1174,17 +1174,17 @@ Process(JSContext *cx, JS::Handle<JSObje
 static int
 usage(void)
 {
     fprintf(gErrFile, "%s\n", JS_GetImplementationVersion());
     fprintf(gErrFile, "usage: xpcshell [-g gredir] [-a appdir] [-r manifest]... [-PsSwWCijmIn] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n");
     return 2;
 }
 
-extern JSClass global_class;
+extern const JSClass global_class;
 
 static void
 ProcessArgsForCompartment(JSContext *cx, char **argv, int argc)
 {
     for (int i = 0; i < argc; i++) {
         if (argv[i][0] != '-' || argv[i][1] == '\0')
             break;
 
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -580,17 +580,17 @@ sandbox_convert(JSContext *cx, HandleObj
     if (type == JSTYPE_OBJECT) {
         vp.set(OBJECT_TO_JSVAL(obj));
         return true;
     }
 
     return JS_ConvertStub(cx, obj, type, vp);
 }
 
-static JSClass SandboxClass = {
+static const JSClass SandboxClass = {
     "Sandbox",
     XPCONNECT_GLOBAL_FLAGS,
     JS_PropertyStub,   JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     sandbox_enumerate, sandbox_resolve, sandbox_convert,  sandbox_finalize,
     NULL, NULL, NULL, NULL, TraceXPCGlobal
 };
 
 static const JSFunctionSpec SandboxFunctions[] = {
@@ -977,17 +977,17 @@ xpc::CreateSandboxObject(JSContext *cx, 
                 RootedValue v(cx, ObjectValue(*options.proto));
                 if (!xpc::WrapperFactory::WaiveXrayAndWrap(cx, v.address()))
                     return NS_ERROR_FAILURE;
                 options.proto = &v.toObject();
             }
 
             // Now check what sort of thing we've got in |proto|
             JSObject *unwrappedProto = js::UncheckedUnwrap(options.proto, false);
-            js::Class *unwrappedClass = js::GetObjectClass(unwrappedProto);
+            const js::Class *unwrappedClass = js::GetObjectClass(unwrappedProto);
             if (IS_WN_CLASS(unwrappedClass) ||
                 mozilla::dom::IsDOMClass(Jsvalify(unwrappedClass))) {
                 // Wrap it up in a proxy that will do the right thing in terms
                 // of this-binding for methods.
                 RootedValue priv(cx, ObjectValue(*options.proto));
                 options.proto = js::NewProxyObject(cx, &xpc::sandboxProxyHandler,
                                                    priv, nullptr, sandbox);
                 if (!options.proto)
--- a/js/xpconnect/src/XPCCallContext.cpp
+++ b/js/xpconnect/src/XPCCallContext.cpp
@@ -63,17 +63,17 @@ XPCCallContext::XPCCallContext(XPCContex
     if (!unwrapped) {
         mWrapper = UnwrapThisIfAllowed(obj, funobj, argc);
         if (!mWrapper) {
             JS_ReportError(mJSContext, "Permission denied to call method on |this|");
             mState = INIT_FAILED;
             return;
         }
     } else {
-        js::Class *clasp = js::GetObjectClass(unwrapped);
+        const js::Class *clasp = js::GetObjectClass(unwrapped);
         if (IS_WN_CLASS(clasp)) {
             mWrapper = XPCWrappedNative::Get(unwrapped);
         } else if (IS_TEAROFF_CLASS(clasp)) {
             mTearOff = (XPCWrappedNativeTearOff*)js::GetObjectPrivate(unwrapped);
             mWrapper = XPCWrappedNative::Get(js::GetObjectParent(unwrapped));
         }
     }
     if (mWrapper) {
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -74,17 +74,17 @@ UnwrapNativeCPOW(nsISupports* wrapper)
 }
 
 /***************************************************************************/
 
 // static
 bool
 XPCConvert::GetISupportsFromJSObject(JSObject* obj, nsISupports** iface)
 {
-    JSClass* jsclass = js::GetObjectJSClass(obj);
+    const JSClass* jsclass = js::GetObjectJSClass(obj);
     MOZ_ASSERT(jsclass, "obj has no class");
     if (jsclass &&
         (jsclass->flags & JSCLASS_HAS_PRIVATE) &&
         (jsclass->flags & JSCLASS_PRIVATE_IS_NSISUPPORTS)) {
         *iface = (nsISupports*) xpc_GetJSPrivate(obj);
         return true;
     }
     *iface = UnwrapDOMObjectToISupports(obj);
--- a/js/xpconnect/src/XPCJSContextStack.cpp
+++ b/js/xpconnect/src/XPCJSContextStack.cpp
@@ -118,17 +118,17 @@ SafeFinalize(JSFreeOp *fop, JSObject* ob
 {
     SandboxPrivate* sop =
         static_cast<SandboxPrivate*>(xpc_GetJSPrivate(obj));
     sop->ForgetGlobalObject();
     NS_IF_RELEASE(sop);
     DestroyProtoAndIfaceCache(obj);
 }
 
-JSClass xpc::SafeJSContextGlobalClass = {
+const JSClass xpc::SafeJSContextGlobalClass = {
     "global_for_XPCJSContextStack_SafeJSContext",
     XPCONNECT_GLOBAL_FLAGS,
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, SafeGlobalResolve, JS_ConvertStub, SafeFinalize,
     NULL, NULL, NULL, NULL, TraceXPCGlobal
 };
 
 JSContext*
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -3119,17 +3119,17 @@ XPCJSRuntime::OnJSContextNew(JSContext *
     XPCContext* xpc = new XPCContext(this, cx);
     if (!xpc)
         return false;
 
     return true;
 }
 
 bool
-XPCJSRuntime::DescribeCustomObjects(JSObject* obj, js::Class* clasp,
+XPCJSRuntime::DescribeCustomObjects(JSObject* obj, const js::Class* clasp,
                                     char (&name)[72]) const
 {
     XPCNativeScriptableInfo *si = nullptr;
 
     if (!IS_PROTO_CLASS(clasp)) {
         return false;
     }
 
@@ -3142,17 +3142,17 @@ XPCJSRuntime::DescribeCustomObjects(JSOb
     }
 
     JS_snprintf(name, sizeof(name), "JS Object (%s - %s)",
                 clasp->name, si->GetJSClass()->name);
     return true;
 }
 
 bool
-XPCJSRuntime::NoteCustomGCThingXPCOMChildren(js::Class* clasp, JSObject* obj,
+XPCJSRuntime::NoteCustomGCThingXPCOMChildren(const js::Class* clasp, JSObject* obj,
                                              nsCycleCollectionTraversalCallback& cb) const
 {
     if (clasp != &XPC_WN_Tearoff_JSClass) {
         return false;
     }
 
     // A tearoff holds a strong reference to its native object
     // (see XPCWrappedNative::FlatJSObjectFinalized). Its XPCWrappedNative
--- a/js/xpconnect/src/XPCQuickStubs.cpp
+++ b/js/xpconnect/src/XPCQuickStubs.cpp
@@ -66,29 +66,29 @@ LookupInterfaceOrAncestor(uint32_t table
     return entry;
 }
 
 static MOZ_ALWAYS_INLINE bool
 HasBitInInterfacesBitmap(JSObject *obj, uint32_t interfaceBit)
 {
     MOZ_ASSERT(IS_WN_REFLECTOR(obj), "Not a wrapper?");
 
-    XPCWrappedNativeJSClass *clasp =
-      (XPCWrappedNativeJSClass*)js::GetObjectClass(obj);
+    const XPCWrappedNativeJSClass *clasp =
+      (const XPCWrappedNativeJSClass*)js::GetObjectClass(obj);
     return (clasp->interfacesBitmap & (1 << interfaceBit)) != 0;
 }
 
 static void
 PointerFinalize(JSFreeOp *fop, JSObject *obj)
 {
     JSPropertyOp *popp = static_cast<JSPropertyOp *>(JS_GetPrivate(obj));
     delete popp;
 }
 
-JSClass
+const JSClass
 PointerHolderClass = {
     "Pointer", JSCLASS_HAS_PRIVATE,
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, PointerFinalize
 };
 
 bool
 xpc_qsDefineQuickStubs(JSContext *cx, JSObject *protoArg, unsigned flags,
@@ -547,17 +547,17 @@ getWrapper(JSContext *cx,
     }
 
     // Handle tearoffs.
     //
     // If |obj| is of the tearoff class, that means we're dealing with a JS
     // object reflection of a particular interface (ie, |foo.nsIBar|). These
     // JS objects are parented to their wrapper, so we snag the tearoff object
     // along the way (if desired), and then set |obj| to its parent.
-    js::Class* clasp = js::GetObjectClass(obj);
+    const js::Class* clasp = js::GetObjectClass(obj);
     if (clasp == &XPC_WN_Tearoff_JSClass) {
         *tearoff = (XPCWrappedNativeTearOff*) js::GetObjectPrivate(obj);
         obj = js::GetObjectParent(obj);
     }
 
     // If we've got a WN, store things the way callers expect. Otherwise, leave
     // things null and return.
     if (IS_WN_CLASS(clasp))
--- a/js/xpconnect/src/XPCQuickStubs.h
+++ b/js/xpconnect/src/XPCQuickStubs.h
@@ -617,17 +617,17 @@ PropertyOpForwarder(JSContext *cx, unsig
     JS::RootedValue argval(cx, (argc > 0) ? args.get(0) : JSVAL_VOID);
     JS::RootedId id(cx);
     if (!JS_ValueToId(cx, v, id.address()))
         return false;
     args.rval().set(argval);
     return ApplyPropertyOp<Op>(cx, *popp, obj, id, args.rval());
 }
 
-extern JSClass PointerHolderClass;
+extern const JSClass PointerHolderClass;
 
 template<typename Op>
 JSObject *
 GeneratePropertyOp(JSContext *cx, JS::HandleObject obj, JS::HandleId id, unsigned argc, Op pop)
 {
     // The JS engine provides two reserved slots on function objects for
     // XPConnect to use. Use them to stick the necessary info here.
     JSFunction *fun =
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -1653,17 +1653,17 @@ nsXPCWrappedJSClass::GetInterfaceName()
     return mName;
 }
 
 static void
 FinalizeStub(JSFreeOp *fop, JSObject *obj)
 {
 }
 
-static JSClass XPCOutParamClass = {
+static const JSClass XPCOutParamClass = {
     "XPCOutParam",
     0,
     JS_PropertyStub,
     JS_DeletePropertyStub,
     JS_PropertyStub,
     JS_StrictPropertyStub,
     JS_EnumerateStub,
     JS_ResolveStub,
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -301,17 +301,17 @@ XPCWrappedNative::WrapNewGlobal(xpcObjec
                                    sciProto, sciMaybe);
 
     // ...and then ScriptableInfo. We need all this stuff now because it's going
     // to tell us the JSClass of the object we're going to create.
     AutoMarkingNativeScriptableInfoPtr si(cx, XPCNativeScriptableInfo::Construct(&sciWrapper));
     MOZ_ASSERT(si.get());
 
     // Finally, we get to the JSClass.
-    JSClass *clasp = si->GetJSClass();
+    const JSClass *clasp = si->GetJSClass();
     MOZ_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL);
 
     // Create the global.
     RootedObject global(cx, xpc::CreateGlobalObject(cx, clasp, principal, aOptions));
     if (!global)
         return NS_ERROR_FAILURE;
     XPCWrappedNativeScope *scope = GetCompartmentPrivate(global)->scope;
 
@@ -1007,17 +1007,17 @@ XPCWrappedNative::Init(HandleObject pare
             if (!mScriptableInfo)
                 return false;
         }
     }
     XPCNativeScriptableInfo* si = mScriptableInfo;
 
     // create our flatJSObject
 
-    JSClass* jsclazz = si ? si->GetJSClass() : Jsvalify(&XPC_WN_NoHelper_JSClass.base);
+    const JSClass* jsclazz = si ? si->GetJSClass() : Jsvalify(&XPC_WN_NoHelper_JSClass.base);
 
     // We should have the global jsclass flag if and only if we're a global.
     MOZ_ASSERT_IF(si, !!si->GetFlags().IsGlobalObject() == !!(jsclazz->flags & JSCLASS_IS_GLOBAL));
 
     MOZ_ASSERT(jsclazz &&
                jsclazz->name &&
                jsclazz->flags &&
                jsclazz->addProperty &&
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -568,17 +568,17 @@ XPC_WN_Shared_Enumerate(JSContext *cx, H
 enum WNHelperType {
     WN_NOHELPER,
     WN_HELPER
 };
 
 static void
 WrappedNativeFinalize(js::FreeOp *fop, JSObject *obj, WNHelperType helperType)
 {
-    js::Class* clazz = js::GetObjectClass(obj);
+    const js::Class* clazz = js::GetObjectClass(obj);
     if (clazz->flags & JSCLASS_DOM_GLOBAL) {
         mozilla::dom::DestroyProtoAndIfaceCache(obj);
     }
     nsISupports* p = static_cast<nsISupports*>(xpc_GetJSPrivate(obj));
     if (!p)
         return;
 
     XPCWrappedNative* wrapper = static_cast<XPCWrappedNative*>(p);
@@ -599,17 +599,17 @@ XPC_WN_NoHelper_Finalize(js::FreeOp *fop
  * engine to mark |obj|. Eventually, this will lead to the trace hook being
  * called for |obj|. The trace hook should call |wrapper->TraceInside|, which
  * should mark any JS objects held by |wrapper| as members.
  */
 
 static void
 MarkWrappedNative(JSTracer *trc, JSObject *obj)
 {
-    js::Class* clazz = js::GetObjectClass(obj);
+    const js::Class* clazz = js::GetObjectClass(obj);
     if (clazz->flags & JSCLASS_DOM_GLOBAL) {
         mozilla::dom::TraceProtoAndIfaceCache(trc, obj);
     }
     MOZ_ASSERT(IS_WN_CLASS(clazz));
 
     XPCWrappedNative *wrapper = XPCWrappedNative::Get(obj);
     if (wrapper && wrapper->IsValid())
         wrapper->TraceInside(trc);
@@ -675,17 +675,17 @@ XPC_WN_OuterObject(JSContext *cx, Handle
         }
 
         obj = newThis;
     }
 
     return obj;
 }
 
-XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
+const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass = {
   { // base
     "XPCWrappedNative_NoHelper",    // name;
     WRAPPER_SLOTS |
     JSCLASS_PRIVATE_IS_NSISUPPORTS, // flags
 
     /* Mandatory non-null function pointer members. */
     XPC_WN_OnlyIWrite_AddPropertyStub, // addProperty
     XPC_WN_CantDeletePropertyStub,     // delProperty
@@ -1023,17 +1023,17 @@ XPC_WN_Helper_NewResolve(JSContext *cx, 
         else
             do shared enumerate - don't use this JSOp thing at all
 */
 
 bool
 XPC_WN_JSOp_Enumerate(JSContext *cx, HandleObject obj, JSIterateOp enum_op,
                       MutableHandleValue statep, MutableHandleId idp)
 {
-    js::Class *clazz = js::GetObjectClass(obj);
+    const js::Class *clazz = js::GetObjectClass(obj);
     if (!IS_WN_CLASS(clazz) || clazz == &XPC_WN_NoHelper_JSClass.base) {
         // obj must be a prototype object or a wrapper w/o a
         // helper. Short circuit this call to the default
         // implementation.
 
         return JS_EnumerateState(cx, obj, enum_op, statep, idp);
     }
 
@@ -1267,17 +1267,17 @@ XPCNativeScriptableShared::PopulateJSCla
 
 #define IS_NOHELPER_CLASS(clasp) (clasp == &XPC_WN_NoHelper_JSClass.base)
 #define IS_CU_CLASS(clasp) (clasp->name[0] == 'n' && !strcmp(clasp->name, "nsXPCComponents_Utils"))
 
 MOZ_ALWAYS_INLINE JSObject*
 FixUpThisIfBroken(JSObject *obj, JSObject *funobj)
 {
     if (funobj) {
-        js::Class *parentClass = js::GetObjectClass(js::GetObjectParent(funobj));
+        const js::Class *parentClass = js::GetObjectClass(js::GetObjectParent(funobj));
         if (MOZ_UNLIKELY((IS_NOHELPER_CLASS(parentClass) || IS_CU_CLASS(parentClass)) &&
                          (js::GetObjectClass(obj) != parentClass)))
         {
             return js::GetObjectParent(funobj);
         }
     }
     return obj;
 }
@@ -1427,17 +1427,17 @@ XPC_WN_ModsAllowed_Proto_Resolve(JSConte
 
     return DefinePropertyIfFound(ccx, obj, id,
                                  self->GetSet(), nullptr, nullptr,
                                  self->GetScope(),
                                  true, nullptr, nullptr, si,
                                  enumFlag, nullptr);
 }
 
-js::Class XPC_WN_ModsAllowed_WithCall_Proto_JSClass = {
+const js::Class XPC_WN_ModsAllowed_WithCall_Proto_JSClass = {
     "XPC_WN_ModsAllowed_WithCall_Proto_JSClass", // name;
     WRAPPER_SLOTS, // flags;
 
     /* Mandatory non-null function pointer members. */
     JS_PropertyStub,                // addProperty;
     JS_DeletePropertyStub,          // delProperty;
     JS_PropertyStub,                // getProperty;
     JS_StrictPropertyStub,          // setProperty;
@@ -1452,17 +1452,17 @@ js::Class XPC_WN_ModsAllowed_WithCall_Pr
     nullptr,                         // construct;
     nullptr,                         // hasInstance;
     XPC_WN_Shared_Proto_Trace,      // trace;
 
     JS_NULL_CLASS_EXT,
     XPC_WN_WithCall_ObjectOps
 };
 
-js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass = {
+const js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass = {
     "XPC_WN_ModsAllowed_NoCall_Proto_JSClass", // name;
     WRAPPER_SLOTS,                  // flags;
 
     /* Mandatory non-null function pointer members. */
     JS_PropertyStub,                // addProperty;
     JS_DeletePropertyStub,          // delProperty;
     JS_PropertyStub,                // getProperty;
     JS_StrictPropertyStub,          // setProperty;
@@ -1539,17 +1539,17 @@ XPC_WN_NoMods_Proto_Resolve(JSContext *c
                                  self->GetSet(), nullptr, nullptr,
                                  self->GetScope(),
                                  true, nullptr, nullptr, si,
                                  JSPROP_READONLY |
                                  JSPROP_PERMANENT |
                                  enumFlag, nullptr);
 }
 
-js::Class XPC_WN_NoMods_WithCall_Proto_JSClass = {
+const js::Class XPC_WN_NoMods_WithCall_Proto_JSClass = {
     "XPC_WN_NoMods_WithCall_Proto_JSClass",    // name;
     WRAPPER_SLOTS,                             // flags;
 
     /* Mandatory non-null function pointer members. */
     XPC_WN_OnlyIWrite_Proto_AddPropertyStub,   // addProperty;
     XPC_WN_CantDeletePropertyStub,             // delProperty;
     JS_PropertyStub,                           // getProperty;
     XPC_WN_OnlyIWrite_Proto_SetPropertyStub,   // setProperty;
@@ -1564,17 +1564,17 @@ js::Class XPC_WN_NoMods_WithCall_Proto_J
     nullptr,                         // construct;
     nullptr,                         // hasInstance;
     XPC_WN_Shared_Proto_Trace,      // trace;
 
     JS_NULL_CLASS_EXT,
     XPC_WN_WithCall_ObjectOps
 };
 
-js::Class XPC_WN_NoMods_NoCall_Proto_JSClass = {
+const js::Class XPC_WN_NoMods_NoCall_Proto_JSClass = {
     "XPC_WN_NoMods_NoCall_Proto_JSClass",      // name;
     WRAPPER_SLOTS,                             // flags;
 
     /* Mandatory non-null function pointer members. */
     XPC_WN_OnlyIWrite_Proto_AddPropertyStub,   // addProperty;
     XPC_WN_CantDeletePropertyStub,             // delProperty;
     JS_PropertyStub,                           // getProperty;
     XPC_WN_OnlyIWrite_Proto_SetPropertyStub,   // setProperty;
@@ -1644,17 +1644,17 @@ XPC_WN_TearOff_Finalize(js::FreeOp *fop,
 {
     XPCWrappedNativeTearOff* p = (XPCWrappedNativeTearOff*)
         xpc_GetJSPrivate(obj);
     if (!p)
         return;
     p->JSObjectFinalized();
 }
 
-js::Class XPC_WN_Tearoff_JSClass = {
+const js::Class XPC_WN_Tearoff_JSClass = {
     "WrappedNative_TearOff",                   // name;
     WRAPPER_SLOTS,                             // flags;
 
     XPC_WN_OnlyIWrite_AddPropertyStub,         // addProperty;
     XPC_WN_CantDeletePropertyStub,             // delProperty;
     JS_PropertyStub,                           // getProperty;
     XPC_WN_OnlyIWrite_SetPropertyStub,         // setProperty;
     XPC_WN_TearOff_Enumerate,                  // enumerate;
--- a/js/xpconnect/src/XPCWrappedNativeProto.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeProto.cpp
@@ -66,17 +66,17 @@ XPCWrappedNativeProto::Init(const XPCNat
                                  nullptr;
     if (callback) {
         mScriptableInfo =
             XPCNativeScriptableInfo::Construct(scriptableCreateInfo);
         if (!mScriptableInfo)
             return false;
     }
 
-    js::Class* jsclazz;
+    const js::Class* jsclazz;
 
     if (mScriptableInfo) {
         const XPCNativeScriptableFlags& flags(mScriptableInfo->GetFlags());
 
         if (flags.AllowPropModsToPrototype()) {
             jsclazz = flags.WantCall() ?
                 &XPC_WN_ModsAllowed_WithCall_Proto_JSClass :
                 &XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -167,17 +167,17 @@ XPCWrappedNativeScope::XPCWrappedNativeS
     // In addition to being pref-controlled, we also disable XBL scopes for
     // remote XUL domains, _except_ if we have an additional pref override set.
     nsIPrincipal *principal = GetPrincipal();
     mAllowXBLScope = !RemoteXULForbidsXBLScope(principal, aGlobal);
 
     // Determine whether to use an XBL scope.
     mUseXBLScope = mAllowXBLScope;
     if (mUseXBLScope) {
-      js::Class *clasp = js::GetObjectClass(mGlobalJSObject);
+      const js::Class *clasp = js::GetObjectClass(mGlobalJSObject);
       mUseXBLScope = !strcmp(clasp->name, "Window") ||
                      !strcmp(clasp->name, "ChromeWindow") ||
                      !strcmp(clasp->name, "ModalContentWindow");
     }
     if (mUseXBLScope) {
       mUseXBLScope = principal && !nsContentUtils::IsSystemPrincipal(principal);
     }
 }
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -399,17 +399,17 @@ TraceXPCGlobal(JSTracer *trc, JSObject *
     if (js::GetObjectClass(obj)->flags & JSCLASS_DOM_GLOBAL)
         mozilla::dom::TraceProtoAndIfaceCache(trc, obj);
 }
 
 #ifdef DEBUG
 #include "mozilla/Preferences.h"
 #include "nsIXULRuntime.h"
 static void
-CheckTypeInference(JSContext *cx, JSClass *clasp, nsIPrincipal *principal)
+CheckTypeInference(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal)
 {
     // Check that the global class isn't whitelisted.
     if (strcmp(clasp->name, "Sandbox") ||
         strcmp(clasp->name, "nsXBLPrototypeScript compilation scope") ||
         strcmp(clasp->name, "nsXULPrototypeScript compilation scope"))
         return;
 
     // Check that the pref is on.
@@ -438,17 +438,17 @@ CheckTypeInference(JSContext *cx, JSClas
 }
 #else
 #define CheckTypeInference(cx, clasp, principal) {}
 #endif
 
 namespace xpc {
 
 JSObject*
-CreateGlobalObject(JSContext *cx, JSClass *clasp, nsIPrincipal *principal,
+CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal,
                    JS::CompartmentOptions& aOptions)
 {
     // Make sure that Type Inference is enabled for everything non-chrome.
     // Sandboxes and compilation scopes are exceptions. See bug 744034.
     CheckTypeInference(cx, clasp, principal);
 
     MOZ_ASSERT(NS_IsMainThread(), "using a principal off the main thread?");
     MOZ_ASSERT(principal);
@@ -462,17 +462,17 @@ CreateGlobalObject(JSContext *cx, JSClas
     // The constructor automatically attaches the scope to the compartment private
     // of |global|.
     (void) new XPCWrappedNativeScope(cx, global);
 
 #ifdef DEBUG
     // Verify that the right trace hook is called. Note that this doesn't
     // work right for wrapped globals, since the tracing situation there is
     // more complicated. Manual inspection shows that they do the right thing.
-    if (!((js::Class*)clasp)->ext.isWrappedNative)
+    if (!((const js::Class*)clasp)->ext.isWrappedNative)
     {
         VerifyTraceXPCGlobalCalledTracer trc;
         JS_TracerInit(&trc.base, JS_GetRuntime(cx), VerifyTraceXPCGlobalCalled);
         trc.ok = false;
         JS_TraceChildren(&trc.base, global, JSTRACE_OBJECT);
         MOZ_ASSERT(trc.ok, "Trace hook on global needs to call TraceXPCGlobal for XPConnect compartments.");
     }
 #endif
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -649,20 +649,20 @@ public:
     XPCWrappedNativeProtoMap* GetDetachedWrappedNativeProtoMap() const
         {return mDetachedWrappedNativeProtoMap;}
 
     XPCLock* GetMapLock() const {return mMapLock;}
 
     bool OnJSContextNew(JSContext* cx);
 
     virtual bool
-    DescribeCustomObjects(JSObject* aObject, js::Class* aClasp,
+    DescribeCustomObjects(JSObject* aObject, const js::Class* aClasp,
                           char (&aName)[72]) const MOZ_OVERRIDE;
     virtual bool
-    NoteCustomGCThingXPCOMChildren(js::Class* aClasp, JSObject* aObj,
+    NoteCustomGCThingXPCOMChildren(const js::Class* aClasp, JSObject* aObj,
                                    nsCycleCollectionTraversalCallback& aCb) const MOZ_OVERRIDE;
 
     /**
      * Infrastructure for classes that need to defer part of the finalization
      * until after the GC has run, for example for objects that we don't want to
      * destroy during the GC.
      */
 
@@ -1109,23 +1109,23 @@ private:
 *
 ****************************************************************************
 ***************************************************************************/
 
 // These are the various JSClasses and callbacks whose use that required
 // visibility from more than one .cpp file.
 
 struct XPCWrappedNativeJSClass;
-extern XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass;
-extern js::Class XPC_WN_NoMods_WithCall_Proto_JSClass;
-extern js::Class XPC_WN_NoMods_NoCall_Proto_JSClass;
-extern js::Class XPC_WN_ModsAllowed_WithCall_Proto_JSClass;
-extern js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
-extern js::Class XPC_WN_Tearoff_JSClass;
-extern js::Class XPC_WN_NoHelper_Proto_JSClass;
+extern const XPCWrappedNativeJSClass XPC_WN_NoHelper_JSClass;
+extern const js::Class XPC_WN_NoMods_WithCall_Proto_JSClass;
+extern const js::Class XPC_WN_NoMods_NoCall_Proto_JSClass;
+extern const js::Class XPC_WN_ModsAllowed_WithCall_Proto_JSClass;
+extern const js::Class XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
+extern const js::Class XPC_WN_Tearoff_JSClass;
+extern const js::Class XPC_WN_NoHelper_Proto_JSClass;
 
 extern bool
 XPC_WN_CallMethod(JSContext *cx, unsigned argc, jsval *vp);
 
 extern bool
 XPC_WN_GetterSetter(JSContext *cx, unsigned argc, jsval *vp);
 
 extern bool
@@ -1190,17 +1190,17 @@ XPC_WN_JSOp_ThisObject(JSContext *cx, JS
         nullptr, /* deleteSpecial */                                          \
         XPC_WN_JSOp_Enumerate,                                                \
         XPC_WN_JSOp_ThisObject,                                               \
     }
 
 // Maybe this macro should check for class->enumerate ==
 // XPC_WN_Shared_Proto_Enumerate or something rather than checking for
 // 4 classes?
-static inline bool IS_PROTO_CLASS(js::Class *clazz)
+static inline bool IS_PROTO_CLASS(const js::Class *clazz)
 {
     return clazz == &XPC_WN_NoMods_WithCall_Proto_JSClass ||
            clazz == &XPC_WN_NoMods_NoCall_Proto_JSClass ||
            clazz == &XPC_WN_ModsAllowed_WithCall_Proto_JSClass ||
            clazz == &XPC_WN_ModsAllowed_NoCall_Proto_JSClass;
 }
 
 /***************************************************************************/
@@ -1821,17 +1821,17 @@ struct XPCWrappedNativeJSClass
 };
 
 class XPCNativeScriptableShared
 {
 public:
     const XPCNativeScriptableFlags& GetFlags() const {return mFlags;}
     uint32_t                        GetInterfacesBitmap() const
         {return mJSClass.interfacesBitmap;}
-    JSClass*                        GetJSClass()
+    const JSClass*                  GetJSClass()
         {return Jsvalify(&mJSClass.base);}
 
     XPCNativeScriptableShared(uint32_t aFlags, char* aName,
                               uint32_t interfacesBitmap)
         : mFlags(aFlags)
         {memset(&mJSClass, 0, sizeof(mJSClass));
          mJSClass.base.name = aName;  // take ownership
          mJSClass.interfacesBitmap = interfacesBitmap;
@@ -1870,17 +1870,17 @@ public:
     GetCallback() const {return mCallback;}
 
     const XPCNativeScriptableFlags&
     GetFlags() const      {return mShared->GetFlags();}
 
     uint32_t
     GetInterfacesBitmap() const {return mShared->GetInterfacesBitmap();}
 
-    JSClass*
+    const JSClass*
     GetJSClass()          {return mShared->GetJSClass();}
 
     XPCNativeScriptableShared*
     GetScriptableShared() {return mShared;}
 
     void
     SetCallback(nsIXPCScriptable* s) {mCallback = s;}
     void
@@ -3611,17 +3611,17 @@ struct SandboxOptions {
     bool wantExportHelpers;
     JS::RootedObject proto;
     nsCString sandboxName;
     JS::RootedObject sameZoneAs;
     DOMConstructors DOMConstructors;
 };
 
 JSObject *
-CreateGlobalObject(JSContext *cx, JSClass *clasp, nsIPrincipal *principal,
+CreateGlobalObject(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal,
                    JS::CompartmentOptions& aOptions);
 
 // Helper for creating a sandbox object to use for evaluating
 // untrusted code completely separated from all other code in the
 // system using EvalInSandbox(). Takes the JSContext on which to
 // do setup etc on, puts the sandbox object in *vp (which must be
 // rooted by the caller), and uses the principal that's either
 // directly passed in prinOrSop or indirectly as an
@@ -3757,17 +3757,17 @@ inline XPCWrappedNativeScope*
 GetObjectScope(JSObject *obj)
 {
     return EnsureCompartmentPrivate(obj)->scope;
 }
 
 extern bool gDebugMode;
 extern bool gDesiredDebugMode;
 
-extern JSClass SafeJSContextGlobalClass;
+extern const JSClass SafeJSContextGlobalClass;
 
 JSObject* NewOutObject(JSContext* cx, JSObject* scope);
 bool IsOutObject(JSContext* cx, JSObject* obj);
 
 nsresult HasInstance(JSContext *cx, JS::HandleObject objArg, const nsID *iid, bool *bp);
 
 } // namespace xpc
 
--- a/js/xpconnect/src/xpcpublic.h
+++ b/js/xpconnect/src/xpcpublic.h
@@ -89,17 +89,17 @@ TraceXPCGlobal(JSTracer *trc, JSObject *
 NS_EXPORT_(bool)
 xpc_LocalizeRuntime(JSRuntime *rt);
 NS_EXPORT_(void)
 xpc_DelocalizeRuntime(JSRuntime *rt);
 
 // If IS_WN_CLASS for the JSClass of an object is true, the object is a
 // wrappednative wrapper, holding the XPCWrappedNative in its private slot.
 
-static inline bool IS_WN_CLASS(js::Class* clazz)
+static inline bool IS_WN_CLASS(const js::Class* clazz)
 {
     return clazz->ext.isWrappedNative;
 }
 static inline bool IS_WN_REFLECTOR(JSObject *obj)
 {
     return IS_WN_CLASS(js::GetObjectClass(obj));
 }
 
--- a/js/xpconnect/wrappers/AccessCheck.cpp
+++ b/js/xpconnect/wrappers/AccessCheck.cpp
@@ -226,17 +226,17 @@ AccessCheck::isCrossOriginAccessPermitte
     // another sane value to pass. For XOWs, we generally want to deny such
     // operations but fail silently (see CrossOriginAccessiblePropertiesOnly::
     // deny). We could just fall through here and rely on the fact that none
     // of the whitelisted properties below will match JSID_VOID, but EIBTI.
     if (id == JSID_VOID)
         return false;
 
     const char *name;
-    js::Class *clasp = js::GetObjectClass(obj);
+    const js::Class *clasp = js::GetObjectClass(obj);
     MOZ_ASSERT(Jsvalify(clasp) != &XrayUtils::HolderClass, "shouldn't have a holder here");
     if (clasp->ext.innerObject)
         name = "Window";
     else
         name = clasp->name;
 
     if (JSID_IS_STRING(id)) {
         if (IsPermitted(name, JSID_TO_FLAT_STRING(id), act == Wrapper::SET))
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -32,34 +32,34 @@ using js::UncheckedUnwrap;
 using js::CheckedUnwrap;
 
 namespace xpc {
 
 static const uint32_t JSSLOT_RESOLVING = 0;
 
 namespace XrayUtils {
 
-JSClass HolderClass = {
+const JSClass HolderClass = {
     "NativePropertyHolder",
     JSCLASS_HAS_RESERVED_SLOTS(2),
     JS_PropertyStub,        JS_DeletePropertyStub, holder_get,      holder_set,
     JS_EnumerateStub,       JS_ResolveStub,  JS_ConvertStub
 };
 }
 
 using namespace XrayUtils;
 
 XrayType
 GetXrayType(JSObject *obj)
 {
     obj = js::UncheckedUnwrap(obj, /* stopAtOuter = */ false);
     if (mozilla::dom::UseDOMXray(obj))
         return XrayForDOMObject;
 
-    js::Class* clasp = js::GetObjectClass(obj);
+    const js::Class* clasp = js::GetObjectClass(obj);
     if (IS_WN_CLASS(clasp) || clasp->ext.innerObject)
         return XrayForWrappedNative;
 
     return NotXray;
 }
 
 ResolvingId::ResolvingId(JSContext *cx, HandleObject wrapper, HandleId id)
   : mId(id),
@@ -323,17 +323,17 @@ GetExpandoObjectPrincipal(JSObject *expa
 static void
 ExpandoObjectFinalize(JSFreeOp *fop, JSObject *obj)
 {
     // Release the principal.
     nsIPrincipal *principal = GetExpandoObjectPrincipal(obj);
     NS_RELEASE(principal);
 }
 
-JSClass ExpandoObjectClass = {
+const JSClass ExpandoObjectClass = {
     "XrayExpandoObject",
     JSCLASS_HAS_RESERVED_SLOTS(JSSLOT_EXPANDO_COUNT),
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, ExpandoObjectFinalize
 };
 
 bool
 XrayTraits::expandoObjectMatchesConsumer(JSContext *cx,
@@ -1079,17 +1079,17 @@ DOMXrayTraits::enumerateNames(JSContext 
     return XrayEnumerateProperties(cx, wrapper, obj, flags, props);
 }
 
 bool
 DOMXrayTraits::call(JSContext *cx, HandleObject wrapper,
                     const JS::CallArgs &args, js::Wrapper& baseInstance)
 {
     RootedObject obj(cx, getTargetObject(wrapper));
-    js::Class* clasp = js::GetObjectClass(obj);
+    const js::Class* clasp = js::GetObjectClass(obj);
     // What we have is either a WebIDL interface object, a WebIDL prototype
     // object, or a WebIDL instance object.  WebIDL prototype objects never have
     // a clasp->call.  WebIDL interface objects we want to invoke on the xray
     // compartment.  WebIDL instance objects either don't have a clasp->call or
     // are using "legacycaller", which basically means plug-ins.  We want to
     // call those on the content compartment.
     if (clasp->flags & JSCLASS_IS_DOMIFACEANDPROTOJSCLASS) {
         if (!clasp->call) {
@@ -1109,17 +1109,17 @@ DOMXrayTraits::call(JSContext *cx, Handl
 }
 
 bool
 DOMXrayTraits::construct(JSContext *cx, HandleObject wrapper,
                          const JS::CallArgs &args, js::Wrapper& baseInstance)
 {
     RootedObject obj(cx, getTargetObject(wrapper));
     MOZ_ASSERT(mozilla::dom::HasConstructor(obj));
-    js::Class* clasp = js::GetObjectClass(obj);
+    const js::Class* clasp = js::GetObjectClass(obj);
     // See comments in DOMXrayTraits::call() explaining what's going on here.
     if (clasp->flags & JSCLASS_IS_DOMIFACEANDPROTOJSCLASS) {
         if (!clasp->construct) {
             js_ReportIsNotFunction(cx, JS::ObjectValue(*wrapper));
             return false;
         }
         if (!clasp->construct(cx, args.length(), args.base()))
             return false;
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -20,17 +20,17 @@ namespace xpc {
 bool
 holder_get(JSContext *cx, JS::HandleObject holder, JS::HandleId id, JS::MutableHandleValue vp);
 bool
 holder_set(JSContext *cx, JS::HandleObject holder, JS::HandleId id, bool strict,
            JS::MutableHandleValue vp);
 
 namespace XrayUtils {
 
-extern JSClass HolderClass;
+extern const JSClass HolderClass;
 
 bool CloneExpandoChain(JSContext *cx, JSObject *src, JSObject *dst);
 
 bool
 IsTransparent(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id);
 
 JSObject *
 GetNativePropertiesObject(JSContext *cx, JSObject *wrapper);
--- a/netwerk/base/src/ProxyAutoConfig.cpp
+++ b/netwerk/base/src/ProxyAutoConfig.cpp
@@ -508,17 +508,17 @@ class JSRuntimeWrapper
 private:
   static const unsigned sRuntimeHeapSize = 2 << 20;
 
   JSRuntime *mRuntime;
   JSContext *mContext;
   JSObject  *mGlobal;
   bool      mOK;
 
-  static JSClass sGlobalClass;
+  static const JSClass sGlobalClass;
 
   JSRuntimeWrapper()
     : mRuntime(nullptr), mContext(nullptr), mGlobal(nullptr), mOK(false)
   {
       MOZ_COUNT_CTOR(JSRuntimeWrapper);
   }
 
   nsresult Init()
@@ -555,17 +555,17 @@ private:
 
     JS::Rooted<JSObject*> rootedGlobal(mContext, mGlobal);
     JS_FireOnNewGlobalObject(mContext, rootedGlobal);
 
     return NS_OK;
   }
 };
 
-JSClass JSRuntimeWrapper::sGlobalClass = {
+const JSClass JSRuntimeWrapper::sGlobalClass = {
   "PACResolutionThreadGlobal",
   JSCLASS_GLOBAL_FLAGS,
   JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
   JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
 };
 
 nsresult
 ProxyAutoConfig::Init(const nsCString &aPACURI,
--- a/startupcache/test/TestStartupCache.cpp
+++ b/startupcache/test/TestStartupCache.cpp
@@ -509,17 +509,17 @@ int main(int argc, char** argv)
   // for now. Eventually, the whole notion of pushing and popping will just go
   // away.
   nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID());
   if (xpc)
     cx = xpc->GetSafeJSContext();
 
   bool use_js = !!cx;
   JSAutoRequest req(cx);
-  static JSClass global_class = {
+  static const JSClass global_class = {
     "global", JSCLASS_NEW_RESOLVE | JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_PRIVATE,
     JS_PropertyStub,  JS_DeletePropertyStub,
     JS_PropertyStub,  JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub,
     JS_ConvertStub
   };
   JSObject *glob = nullptr;
   if (use_js)
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -672,17 +672,17 @@ JSHistogram_Clear(JSContext *cx, unsigne
   Histogram *h = static_cast<Histogram*>(JS_GetPrivate(obj));
   h->Clear();
   return true;
 }
 
 nsresult
 WrapAndReturnHistogram(Histogram *h, JSContext *cx, JS::Value *ret)
 {
-  static JSClass JSHistogram_class = {
+  static const JSClass JSHistogram_class = {
     "JSHistogram",  /* name */
     JSCLASS_HAS_PRIVATE, /* flags */
     JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
     JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
   };
 
   JS::Rooted<JSObject*> obj(cx, JS_NewObject(cx, &JSHistogram_class, nullptr, nullptr));
   if (!obj)
--- a/tools/profiler/SaveProfileTask.cpp
+++ b/tools/profiler/SaveProfileTask.cpp
@@ -53,17 +53,17 @@ SaveProfileTask::Run() {
   cx = JS_NewContext(rt, 8192);
   if (!cx) {
     LOG("Failed to get context");
     return NS_ERROR_FAILURE;
   }
 
   {
     JSAutoRequest ar(cx);
-    static JSClass c = {
+    static const JSClass c = {
       "global", JSCLASS_GLOBAL_FLAGS,
       JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
       JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub
     };
     JSObject *obj = JS_NewGlobalObject(cx, &c, NULL, JS::FireOnNewGlobalHook);
 
     std::ofstream stream;
     stream.open(tmpPath.get());
--- a/xpcom/base/CycleCollectedJSRuntime.cpp
+++ b/xpcom/base/CycleCollectedJSRuntime.cpp
@@ -506,17 +506,17 @@ CycleCollectedJSRuntime::DescribeGCThing
   if (!aCb.WantDebugInfo()) {
     aCb.DescribeGCedNode(aIsMarked, "JS Object");
     return;
   }
 
   char name[72];
   if (aTraceKind == JSTRACE_OBJECT) {
     JSObject* obj = static_cast<JSObject*>(aThing);
-    js::Class* clasp = js::GetObjectClass(obj);
+    const js::Class* clasp = js::GetObjectClass(obj);
 
     // Give the subclass a chance to do something
     if (DescribeCustomObjects(obj, clasp, name)) {
       // Nothing else to do!
     } else if (js::IsFunctionObject(obj)) {
       JSFunction* fun = JS_GetObjectFunction(obj);
       JSString* str = JS_GetFunctionDisplayId(fun);
       if (str) {
@@ -557,17 +557,17 @@ CycleCollectedJSRuntime::NoteGCThingJSCh
   MOZ_ASSERT(mJSRuntime);
   TraversalTracer trc(aCb);
   JS_TracerInit(&trc, mJSRuntime, NoteJSChildTracerShim);
   trc.eagerlyTraceWeakMaps = DoNotTraceWeakMaps;
   JS_TraceChildren(&trc, aThing, aTraceKind);
 }
 
 void
-CycleCollectedJSRuntime::NoteGCThingXPCOMChildren(js::Class* aClasp, JSObject* aObj,
+CycleCollectedJSRuntime::NoteGCThingXPCOMChildren(const js::Class* aClasp, JSObject* aObj,
                                                   nsCycleCollectionTraversalCallback& aCb) const
 {
   MOZ_ASSERT(aClasp);
   MOZ_ASSERT(aClasp == js::GetObjectClass(aObj));
 
   if (NoteCustomGCThingXPCOMChildren(aClasp, aObj, aCb)) {
     // Nothing else to do!
     return;
--- a/xpcom/base/CycleCollectedJSRuntime.h
+++ b/xpcom/base/CycleCollectedJSRuntime.h
@@ -101,32 +101,32 @@ protected:
 
 private:
 
   void
   DescribeGCThing(bool aIsMarked, void* aThing, JSGCTraceKind aTraceKind,
                   nsCycleCollectionTraversalCallback& aCb) const;
 
   virtual bool
-  DescribeCustomObjects(JSObject* aObject, js::Class* aClasp,
+  DescribeCustomObjects(JSObject* aObject, const js::Class* aClasp,
                         char (&aName)[72]) const
   {
     return false; // We did nothing.
   }
 
   void
   NoteGCThingJSChildren(void* aThing, JSGCTraceKind aTraceKind,
                         nsCycleCollectionTraversalCallback& aCb) const;
 
   void
-  NoteGCThingXPCOMChildren(js::Class* aClasp, JSObject* aObj,
+  NoteGCThingXPCOMChildren(const js::Class* aClasp, JSObject* aObj,
                            nsCycleCollectionTraversalCallback& aCb) const;
 
   virtual bool
-  NoteCustomGCThingXPCOMChildren(js::Class* aClasp, JSObject* aObj,
+  NoteCustomGCThingXPCOMChildren(const js::Class* aClasp, JSObject* aObj,
                                  nsCycleCollectionTraversalCallback& aCb) const
   {
     return false; // We did nothing.
   }
 
   enum TraverseSelect {
       TRAVERSE_CPP,
       TRAVERSE_FULL