Bug 933681 - Define JSStdName tables in terms of jsprototypes.h. r=jorendorff
authorBobby Holley <bobbyholley@gmail.com>
Fri, 22 Nov 2013 10:55:42 -0800
changeset 157161 72db5a6ae5c8c5e345eb51e51d93c7086e72c3e4
parent 157160 30bbe45c775e205462b9dee6cfe4aae68591ec5f
child 157162 497280442d1ddcbaee8b70a6e57770d15f6a0638
push id25703
push userphilringnalda@gmail.com
push dateSat, 23 Nov 2013 16:19:02 +0000
treeherdermozilla-central@ad6589ed742c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs933681
milestone28.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 933681 - Define JSStdName tables in terms of jsprototypes.h. r=jorendorff This makes sure everything is consistent, and lets us use JSProtoKeys to index into the JSStdNames table.
js/src/jsapi.cpp
js/src/jsatom.cpp
js/src/jsatom.h
js/src/jsobj.cpp
js/src/jsprototypes.h
js/src/jspubtd.h
js/src/vm/Runtime.h
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -1157,72 +1157,57 @@ JS_InitStandardClasses(JSContext *cx, JS
     return GlobalObject::initStandardClasses(cx, global);
 }
 
 #define CLASP(name)                 (&name##Class)
 #define OCLASP(name)                (&name##Object::class_)
 #define TYPED_ARRAY_CLASP(type)     (&TypedArrayObject::classes[ScalarTypeRepresentation::type])
 #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)
+
+static JSObject *
+DummyInit(JSContext *cx, HandleObject obj)
+{
+    MOZ_ASSUME_UNREACHABLE();
+    return nullptr;
+}
 
 typedef struct JSStdName {
     ClassInitializerOp init;
     size_t      atomOffset;     /* offset of atom pointer in JSAtomState */
     const Class *clasp;
+    bool isDummy() const { return init == DummyInit; };
 } JSStdName;
 
 static const JSStdName*
 LookupStdName(JSRuntime *rt, HandleString name, const JSStdName *table)
 {
     MOZ_ASSERT(name->isAtom());
     for (unsigned i = 0; table[i].init; i++) {
-        JS_ASSERT(table[i].clasp);
+        if (table[i].isDummy())
+            continue;
         JSAtom *atom = AtomStateOffsetToName(rt->atomState, table[i].atomOffset);
         MOZ_ASSERT(atom);
         if (name == atom)
             return &table[i];
     }
 
     return nullptr;
 }
 
 /*
- * Table of class initializers and their atom offsets in rt->atomState.
- * If you add a "standard" class, remember to update this table.
+ * Table of standard classes, indexed by JSProtoKey. For entries where the
+ * JSProtoKey does not correspond to a class with a meaningful constructor, we
+ * insert a null entry into the table.
  */
+#define STD_NAME_ENTRY(name, code, init, clasp) { init, EAGER_CLASS_ATOM(name), clasp },
+#define STD_DUMMY_ENTRY(name, code, init, dummy) { DummyInit, 0, nullptr },
 static const JSStdName standard_class_atoms[] = {
-    {js_InitFunctionClass,              EAGER_CLASS_ATOM(Function), &JSFunction::class_},
-    {js_InitObjectClass,                EAGER_CLASS_ATOM(Object), &JSObject::class_},
-    {js_InitArrayClass,                 EAGER_ATOM_AND_OCLASP(Array)},
-    {js_InitBooleanClass,               EAGER_ATOM_AND_OCLASP(Boolean)},
-    {js_InitDateClass,                  EAGER_ATOM_AND_OCLASP(Date)},
-    {js_InitMathClass,                  EAGER_ATOM_AND_CLASP(Math)},
-    {js_InitNumberClass,                EAGER_ATOM_AND_OCLASP(Number)},
-    {js_InitStringClass,                EAGER_ATOM_AND_OCLASP(String)},
-    {js_InitExceptionClasses,           EAGER_ATOM_AND_OCLASP(Error)},
-    {js_InitRegExpClass,                EAGER_ATOM_AND_OCLASP(RegExp)},
-    {js_InitIteratorClasses,            EAGER_ATOM_AND_OCLASP(StopIteration)},
-    {js_InitJSONClass,                  EAGER_ATOM_AND_CLASP(JSON)},
-    {js_InitTypedArrayClasses,          EAGER_CLASS_ATOM(ArrayBuffer), &js::ArrayBufferObject::protoClass},
-    {js_InitWeakMapClass,               EAGER_ATOM_AND_OCLASP(WeakMap)},
-    {js_InitMapClass,                   EAGER_ATOM_AND_OCLASP(Map)},
-    {js_InitSetClass,                   EAGER_ATOM_AND_OCLASP(Set)},
-#ifdef ENABLE_PARALLEL_JS
-    {js_InitParallelArrayClass,         EAGER_ATOM_AND_OCLASP(ParallelArray)},
-#endif
-    {js_InitProxyClass,                 EAGER_CLASS_ATOM(Proxy), &ProxyObject::uncallableClass_},
-#if EXPOSE_INTL_API
-    {js_InitIntlClass,                  EAGER_ATOM_AND_CLASP(Intl)},
-#endif
-#ifdef ENABLE_BINARYDATA
-    {js_InitTypedObjectClass,           EAGER_ATOM_AND_CLASP(TypedObject)},
-#endif
-    {nullptr,                           0, nullptr}
+  JS_FOR_PROTOTYPES(STD_NAME_ENTRY, STD_DUMMY_ENTRY)
+  { nullptr, 0, nullptr }
 };
 
 /*
  * Table of top-level function and constant names and their init functions.
  * If you add a "standard" global function or property, remember to update
  * this table.
  */
 static const JSStdName standard_class_names[] = {
@@ -1242,42 +1227,16 @@ static const JSStdName standard_class_na
     {js_InitStringClass,        EAGER_ATOM(decodeURI), OCLASP(String)},
     {js_InitStringClass,        EAGER_ATOM(encodeURI), OCLASP(String)},
     {js_InitStringClass,        EAGER_ATOM(decodeURIComponent), OCLASP(String)},
     {js_InitStringClass,        EAGER_ATOM(encodeURIComponent), OCLASP(String)},
 #if JS_HAS_UNEVAL
     {js_InitStringClass,        EAGER_ATOM(uneval), OCLASP(String)},
 #endif
 
-    /* Exception constructors. */
-    {js_InitExceptionClasses,   EAGER_CLASS_ATOM(Error), OCLASP(Error)},
-    {js_InitExceptionClasses,   EAGER_CLASS_ATOM(InternalError), OCLASP(Error)},
-    {js_InitExceptionClasses,   EAGER_CLASS_ATOM(EvalError), OCLASP(Error)},
-    {js_InitExceptionClasses,   EAGER_CLASS_ATOM(RangeError), OCLASP(Error)},
-    {js_InitExceptionClasses,   EAGER_CLASS_ATOM(ReferenceError), OCLASP(Error)},
-    {js_InitExceptionClasses,   EAGER_CLASS_ATOM(SyntaxError), OCLASP(Error)},
-    {js_InitExceptionClasses,   EAGER_CLASS_ATOM(TypeError), OCLASP(Error)},
-    {js_InitExceptionClasses,   EAGER_CLASS_ATOM(URIError), OCLASP(Error)},
-
-    {js_InitIteratorClasses,    EAGER_CLASS_ATOM(Iterator), &PropertyIteratorObject::class_},
-
-    /* Typed Arrays */
-    {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(ArrayBuffer),  &ArrayBufferObject::class_},
-    {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(Int8Array),    TYPED_ARRAY_CLASP(TYPE_INT8)},
-    {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(Uint8Array),   TYPED_ARRAY_CLASP(TYPE_UINT8)},
-    {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(Int16Array),   TYPED_ARRAY_CLASP(TYPE_INT16)},
-    {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(Uint16Array),  TYPED_ARRAY_CLASP(TYPE_UINT16)},
-    {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(Int32Array),   TYPED_ARRAY_CLASP(TYPE_INT32)},
-    {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(Uint32Array),  TYPED_ARRAY_CLASP(TYPE_UINT32)},
-    {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(Float32Array), TYPED_ARRAY_CLASP(TYPE_FLOAT32)},
-    {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(Float64Array), TYPED_ARRAY_CLASP(TYPE_FLOAT64)},
-    {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(Uint8ClampedArray),
-                                TYPED_ARRAY_CLASP(TYPE_UINT8_CLAMPED)},
-    {js_InitTypedArrayClasses,  EAGER_CLASS_ATOM(DataView),     &DataViewObject::class_},
-
     {nullptr,                     0, nullptr}
 };
 
 static const JSStdName object_prototype_names[] = {
     /* Object.prototype properties (global delegates to Object.prototype). */
     {js_InitObjectClass,        EAGER_ATOM(proto), &JSObject::class_},
 #if JS_HAS_TOSOURCE
     {js_InitObjectClass,        EAGER_ATOM(toSource), &JSObject::class_},
@@ -1302,17 +1261,16 @@ static const JSStdName object_prototype_
     {nullptr,                   0, nullptr}
 };
 
 #undef CLASP
 #undef TYPED_ARRAY_CLASP
 #undef EAGER_ATOM
 #undef EAGER_CLASS_ATOM
 #undef EAGER_ATOM_CLASP
-#undef EAGER_ATOM_AND_CLASP
 
 JS_PUBLIC_API(bool)
 JS_ResolveStandardClass(JSContext *cx, HandleObject obj, HandleId id, bool *resolved)
 {
     JSRuntime *rt;
     const JSStdName *stdnm;
 
     AssertHeapIsIdle(cx);
@@ -1395,17 +1353,17 @@ JS_EnumerateStandardClasses(JSContext *c
                                   JS_PropertyStub, JS_StrictPropertyStub,
                                   JSPROP_PERMANENT | JSPROP_READONLY)) {
         return false;
     }
 
     /* Initialize any classes that have not been initialized yet. */
     for (unsigned i = 0; standard_class_atoms[i].init; i++) {
         const JSStdName &stdnm = standard_class_atoms[i];
-        if (!obj->as<GlobalObject>().isStandardClassResolved(stdnm.clasp)) {
+        if (!stdnm.isDummy() && !obj->as<GlobalObject>().isStandardClassResolved(stdnm.clasp)) {
             if (!stdnm.init(cx, obj))
                 return false;
         }
     }
 
     return true;
 }
 
--- a/js/src/jsatom.cpp
+++ b/js/src/jsatom.cpp
@@ -49,17 +49,17 @@ const char * const js::TypeStrings[] = {
     js_object_str,
     js_function_str,
     js_string_str,
     js_number_str,
     js_boolean_str,
     js_null_str,
 };
 
-#define DEFINE_PROTO_STRING(name,code,init) const char js_##name##_str[] = #name;
+#define DEFINE_PROTO_STRING(name,code,init,clasp) const char js_##name##_str[] = #name;
 JS_FOR_EACH_PROTOTYPE(DEFINE_PROTO_STRING)
 #undef DEFINE_PROTO_STRING
 
 #define CONST_CHAR_STR(idpart, id, text) const char js_##idpart##_str[] = text;
 FOR_EACH_COMMON_PROPERTYNAME(CONST_CHAR_STR)
 #undef CONST_CHAR_STR
 
 /* Constant strings that are not atomized. */
@@ -144,17 +144,17 @@ struct CommonNameInfo
 
 bool
 js::InitCommonNames(JSContext *cx)
 {
     static const CommonNameInfo cachedNames[] = {
 #define COMMON_NAME_INFO(idpart, id, text) { js_##idpart##_str, sizeof(text) - 1 },
         FOR_EACH_COMMON_PROPERTYNAME(COMMON_NAME_INFO)
 #undef COMMON_NAME_INFO
-#define COMMON_NAME_INFO(name, code, init) { js_##name##_str, sizeof(#name) - 1 },
+#define COMMON_NAME_INFO(name, code, init, clasp) { js_##name##_str, sizeof(#name) - 1 },
         JS_FOR_EACH_PROTOTYPE(COMMON_NAME_INFO)
 #undef COMMON_NAME_INFO
     };
 
     FixedHeapPtr<PropertyName> *names = &cx->runtime()->firstCachedName;
     for (size_t i = 0; i < ArrayLength(cachedNames); i++, names++) {
         JSAtom *atom = Atomize(cx, cachedNames[i].str, cachedNames[i].length, InternAtom);
         if (!atom)
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -103,17 +103,17 @@ typedef HashSet<AtomStateEntry, AtomHash
 class PropertyName;
 
 }  /* namespace js */
 
 extern bool
 AtomIsInterned(JSContext *cx, JSAtom *atom);
 
 /* Well-known predefined C strings. */
-#define DECLARE_PROTO_STR(name,code,init) extern const char js_##name##_str[];
+#define DECLARE_PROTO_STR(name,code,init,clasp) extern const char js_##name##_str[];
 JS_FOR_EACH_PROTOTYPE(DECLARE_PROTO_STR)
 #undef DECLARE_PROTO_STR
 
 #define DECLARE_CONST_CHAR_STR(idpart, id, text)  extern const char js_##idpart##_str[];
 FOR_EACH_COMMON_PROPERTYNAME(DECLARE_CONST_CHAR_STR)
 #undef DECLARE_CONST_CHAR_STR
 
 /* Constant strings that are not atomized. */
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -2902,23 +2902,23 @@ JSObject::shrinkElements(ThreadSafeConte
 
 static JSObject *
 js_InitNullClass(JSContext *cx, HandleObject obj)
 {
     JS_ASSERT(0);
     return nullptr;
 }
 
-#define DECLARE_PROTOTYPE_CLASS_INIT(name,code,init) \
+#define DECLARE_PROTOTYPE_CLASS_INIT(name,code,init,clasp) \
     extern JSObject *init(JSContext *cx, Handle<JSObject*> obj);
 JS_FOR_EACH_PROTOTYPE(DECLARE_PROTOTYPE_CLASS_INIT)
 #undef DECLARE_PROTOTYPE_CLASS_INIT
 
 static const ClassInitializerOp lazy_prototype_init[JSProto_LIMIT] = {
-#define LAZY_PROTOTYPE_INIT(name,code,init) init,
+#define LAZY_PROTOTYPE_INIT(name,code,init,clasp) init,
     JS_FOR_EACH_PROTOTYPE(LAZY_PROTOTYPE_INIT)
 #undef LAZY_PROTOTYPE_INIT
 };
 
 bool
 js::SetClassAndProto(JSContext *cx, HandleObject obj,
                      const Class *clasp, Handle<js::TaggedProto> proto, bool checkForCycles)
 {
@@ -5386,17 +5386,17 @@ js_GetObjectSlotName(JSTracer *trc, char
             shape = shape->previous();
     } else {
         shape = nullptr;
     }
 
     if (!shape) {
         const char *slotname = nullptr;
         if (obj->is<GlobalObject>()) {
-#define TEST_SLOT_MATCHES_PROTOTYPE(name,code,init)                           \
+#define TEST_SLOT_MATCHES_PROTOTYPE(name,code,init,clasp)                     \
             if ((code) == slot) { slotname = js_##name##_str; goto found; }
             JS_FOR_EACH_PROTOTYPE(TEST_SLOT_MATCHES_PROTOTYPE)
 #undef TEST_SLOT_MATCHES_PROTOTYPE
         }
       found:
         if (slotname)
             JS_snprintf(buf, bufsize, "CLASS_OBJECT(%s)", slotname);
         else
--- a/js/src/jsprototypes.h
+++ b/js/src/jsprototypes.h
@@ -1,60 +1,101 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * 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/. */
 
-/* A higher-order macro for enumerating all JSProtoKey values. */
-
 #ifndef jsprototypes_h
 #define jsprototypes_h
 
+/* A higher-order macro for enumerating all JSProtoKey values. */
 /*
- * Enumerator codes in the second column must not change -- they are part of
- * the JS XDR API.  Also note the symbols in the third column are extern "C";
- * clients should use extern "C" {} as appropriate when using this macro.
+ * Consumers define macros as follows:
+ * macro(name, code, init, clasp)
+ *   name:    The canonical name of the class.
+ *   code:    The enumerator code. There are part of the XDR API, and must not change.
+ *   init:    Initialization function. These are |extern "C";|, and clients should use
+ *            |extern "C" {}| as appropriate when using this macro.
+ *   clasp:   The JSClass for this object, or "dummy" if it doesn't exist.
+ *
+ *
+ * Consumers wishing to iterate over all the JSProtoKey values, can use
+ * JS_FOR_EACH_PROTOTYPE. However, there are certain values that don't correspond
+ * to real constructors, like Null or constructors that are disabled via
+ * preprocessor directives. We still need to include these in the JSProtoKey list
+ * in order to maintain binary XDR compatibility, but we need to provide a tool
+ * to handle them differently. JS_FOR_PROTOTYPES fills this niche.
+ *
+ * Consumers pass two macros to JS_FOR_PROTOTYPES - |real| and |imaginary|. The
+ * former is invoked for entries that have real client-exposed constructors, and
+ * the latter is called for the rest. Consumers that don't care about this
+ * distinction can simply pass the same macro to both, which is exactly what
+ * JS_FOR_EACH_PROTOTYPE does.
  */
 
-#define JS_FOR_EACH_PROTOTYPE(macro) \
-    macro(Null,                   0,     js_InitNullClass) \
-    macro(Object,                 1,     js_InitObjectClass) \
-    macro(Function,               2,     js_InitFunctionClass) \
-    macro(Array,                  3,     js_InitArrayClass) \
-    macro(Boolean,                4,     js_InitBooleanClass) \
-    macro(JSON,                   5,     js_InitJSONClass) \
-    macro(Date,                   6,     js_InitDateClass) \
-    macro(Math,                   7,     js_InitMathClass) \
-    macro(Number,                 8,     js_InitNumberClass) \
-    macro(String,                 9,     js_InitStringClass) \
-    macro(RegExp,                10,     js_InitRegExpClass) \
-    macro(Error,                 11,     js_InitExceptionClasses) \
-    macro(InternalError,         12,     js_InitExceptionClasses) \
-    macro(EvalError,             13,     js_InitExceptionClasses) \
-    macro(RangeError,            14,     js_InitExceptionClasses) \
-    macro(ReferenceError,        15,     js_InitExceptionClasses) \
-    macro(SyntaxError,           16,     js_InitExceptionClasses) \
-    macro(TypeError,             17,     js_InitExceptionClasses) \
-    macro(URIError,              18,     js_InitExceptionClasses) \
-    macro(Iterator,              19,     js_InitIteratorClasses) \
-    macro(StopIteration,         20,     js_InitIteratorClasses) \
-    macro(ArrayBuffer,           21,     js_InitTypedArrayClasses) \
-    macro(Int8Array,             22,     js_InitTypedArrayClasses) \
-    macro(Uint8Array,            23,     js_InitTypedArrayClasses) \
-    macro(Int16Array,            24,     js_InitTypedArrayClasses) \
-    macro(Uint16Array,           25,     js_InitTypedArrayClasses) \
-    macro(Int32Array,            26,     js_InitTypedArrayClasses) \
-    macro(Uint32Array,           27,     js_InitTypedArrayClasses) \
-    macro(Float32Array,          28,     js_InitTypedArrayClasses) \
-    macro(Float64Array,          29,     js_InitTypedArrayClasses) \
-    macro(Uint8ClampedArray,     30,     js_InitTypedArrayClasses) \
-    macro(Proxy,                 31,     js_InitProxyClass) \
-    macro(WeakMap,               32,     js_InitWeakMapClass) \
-    macro(Map,                   33,     js_InitMapClass) \
-    macro(Set,                   34,     js_InitSetClass) \
-    macro(DataView,              35,     js_InitTypedArrayClasses) \
-    macro(ParallelArray,         36,     js_InitParallelArrayClass) \
-    macro(Intl,                  37,     js_InitIntlClass) \
-    macro(TypedObject,           38,     js_InitTypedObjectClass) \
-    macro(GeneratorFunction,     39,     js_InitIteratorClasses) \
+#define CLASP(name)                 (&name##Class)
+#define OCLASP(name)                (&name##Object::class_)
+#define TYPED_ARRAY_CLASP(type)     (&TypedArrayObject::classes[ScalarTypeRepresentation::type])
+
+#ifdef ENABLE_PARALLEL_JS
+#define IF_PJS(real,imaginary) real
+#else
+#define IF_PJS(real,imaginary) imaginary
+#endif
+
+#ifdef EXPOSE_INTL_API
+#define IF_INTL(real,imaginary) real
+#else
+#define IF_INTL(real,imaginary) imaginary
+#endif
+
+#ifdef ENABLE_BINARYDATA
+#define IF_BDATA(real,imaginary) real
+#else
+#define IF_BDATA(real,imaginary) imaginary
+#endif
+
+#define JS_FOR_PROTOTYPES(real,imaginary) \
+    imaginary(Null,              0,     js_InitNullClass,          dummy) \
+    real(Object,                 1,     js_InitObjectClass,        &JSObject::class_) \
+    real(Function,               2,     js_InitFunctionClass,      &JSFunction::class_) \
+    real(Array,                  3,     js_InitArrayClass,         OCLASP(Array)) \
+    real(Boolean,                4,     js_InitBooleanClass,       OCLASP(Boolean)) \
+    real(JSON,                   5,     js_InitJSONClass,          CLASP(JSON)) \
+    real(Date,                   6,     js_InitDateClass,          OCLASP(Date)) \
+    real(Math,                   7,     js_InitMathClass,          CLASP(Math)) \
+    real(Number,                 8,     js_InitNumberClass,        OCLASP(Number)) \
+    real(String,                 9,     js_InitStringClass,        OCLASP(String)) \
+    real(RegExp,                10,     js_InitRegExpClass,        OCLASP(RegExp)) \
+    real(Error,                 11,     js_InitExceptionClasses,   OCLASP(Error)) \
+    real(InternalError,         12,     js_InitExceptionClasses,   OCLASP(Error)) \
+    real(EvalError,             13,     js_InitExceptionClasses,   OCLASP(Error)) \
+    real(RangeError,            14,     js_InitExceptionClasses,   OCLASP(Error)) \
+    real(ReferenceError,        15,     js_InitExceptionClasses,   OCLASP(Error)) \
+    real(SyntaxError,           16,     js_InitExceptionClasses,   OCLASP(Error)) \
+    real(TypeError,             17,     js_InitExceptionClasses,   OCLASP(Error)) \
+    real(URIError,              18,     js_InitExceptionClasses,   OCLASP(Error)) \
+    real(Iterator,              19,     js_InitIteratorClasses,    OCLASP(PropertyIterator)) \
+    real(StopIteration,         20,     js_InitIteratorClasses,    OCLASP(StopIteration)) \
+    real(ArrayBuffer,           21,     js_InitTypedArrayClasses,  &js::ArrayBufferObject::protoClass) \
+    real(Int8Array,             22,     js_InitTypedArrayClasses,  TYPED_ARRAY_CLASP(TYPE_INT8)) \
+    real(Uint8Array,            23,     js_InitTypedArrayClasses,  TYPED_ARRAY_CLASP(TYPE_UINT8)) \
+    real(Int16Array,            24,     js_InitTypedArrayClasses,  TYPED_ARRAY_CLASP(TYPE_INT16)) \
+    real(Uint16Array,           25,     js_InitTypedArrayClasses,  TYPED_ARRAY_CLASP(TYPE_UINT16)) \
+    real(Int32Array,            26,     js_InitTypedArrayClasses,  TYPED_ARRAY_CLASP(TYPE_INT32)) \
+    real(Uint32Array,           27,     js_InitTypedArrayClasses,  TYPED_ARRAY_CLASP(TYPE_UINT32)) \
+    real(Float32Array,          28,     js_InitTypedArrayClasses,  TYPED_ARRAY_CLASP(TYPE_FLOAT32)) \
+    real(Float64Array,          29,     js_InitTypedArrayClasses,  TYPED_ARRAY_CLASP(TYPE_FLOAT64)) \
+    real(Uint8ClampedArray,     30,     js_InitTypedArrayClasses,  TYPED_ARRAY_CLASP(TYPE_UINT8_CLAMPED)) \
+    real(Proxy,                 31,     js_InitProxyClass,         &ProxyObject::uncallableClass_) \
+    real(WeakMap,               32,     js_InitWeakMapClass,       OCLASP(WeakMap)) \
+    real(Map,                   33,     js_InitMapClass,           OCLASP(Map)) \
+    real(Set,                   34,     js_InitSetClass,           OCLASP(Set)) \
+    real(DataView,              35,     js_InitTypedArrayClasses,  OCLASP(DataView)) \
+IF_PJS(real,imaginary)  (ParallelArray,         36,     js_InitParallelArrayClass, OCLASP(ParallelArray)) \
+IF_INTL(real,imaginary) (Intl,                  37,     js_InitIntlClass,          CLASP(Intl)) \
+IF_BDATA(real,imaginary)(TypedObject,           38,     js_InitTypedObjectClass,   CLASP(TypedObject)) \
+    imaginary(GeneratorFunction,     39,     js_InitIteratorClasses, dummy) \
+
+#define JS_FOR_EACH_PROTOTYPE(macro) JS_FOR_PROTOTYPES(macro,macro)
 
 #endif /* jsprototypes_h */
--- a/js/src/jspubtd.h
+++ b/js/src/jspubtd.h
@@ -68,17 +68,17 @@ typedef enum JSType {
     JSTYPE_NUMBER,              /* number */
     JSTYPE_BOOLEAN,             /* boolean */
     JSTYPE_NULL,                /* null */
     JSTYPE_LIMIT
 } JSType;
 
 /* Dense index into cached prototypes and class atoms for standard objects. */
 typedef enum JSProtoKey {
-#define PROTOKEY_AND_INITIALIZER(name,code,init) JSProto_##name = code,
+#define PROTOKEY_AND_INITIALIZER(name,code,init,clasp) JSProto_##name = code,
     JS_FOR_EACH_PROTOTYPE(PROTOKEY_AND_INITIALIZER)
 #undef PROTOKEY_AND_INITIALIZER
     JSProto_LIMIT
 } JSProtoKey;
 
 /* js_CheckAccess mode enumeration. */
 typedef enum JSAccessMode {
     JSACC_PROTO  = 0,           /* XXXbe redundant w.r.t. id */
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -441,17 +441,17 @@ struct RuntimeSizes;
 }
 
 /* Various built-in or commonly-used names pinned on first context. */
 struct JSAtomState
 {
 #define PROPERTYNAME_FIELD(idpart, id, text) js::FixedHeapPtr<js::PropertyName> id;
     FOR_EACH_COMMON_PROPERTYNAME(PROPERTYNAME_FIELD)
 #undef PROPERTYNAME_FIELD
-#define PROPERTYNAME_FIELD(name, code, init) js::FixedHeapPtr<js::PropertyName> name;
+#define PROPERTYNAME_FIELD(name, code, init, clasp) js::FixedHeapPtr<js::PropertyName> name;
     JS_FOR_EACH_PROTOTYPE(PROPERTYNAME_FIELD)
 #undef PROPERTYNAME_FIELD
 };
 
 namespace js {
 
 #define NAME_OFFSET(name)       offsetof(JSAtomState, name)