Bug 880041 (part 1) - Introduce JSObject::{is,as} template functions, and use them for ModuleObject. r=nnethercote.
authorJason Orendorff <jorendorff@mozilla.com>
Sun, 16 Jun 2013 16:47:30 -0700
changeset 135230 55db3dd4779bffc2304aa12241b03734cde44889
parent 135229 f2d55d17a0d88c1698ccfc2279a2d47dd4295540
child 135231 a741a5faa4d3268ab3f263d7e79098e3385bd5e0
push id29584
push usernnethercote@mozilla.com
push dateMon, 17 Jun 2013 05:34:23 +0000
treeherdermozilla-inbound@90b688861270 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnnethercote
bugs880041
milestone24.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 880041 (part 1) - Introduce JSObject::{is,as} template functions, and use them for ModuleObject. r=nnethercote.
js/src/builtin/Module.cpp
js/src/builtin/Module.h
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
js/src/frontend/SharedContext.h
js/src/jsobj.h
--- a/js/src/builtin/Module.cpp
+++ b/js/src/builtin/Module.cpp
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "builtin/Module.h"
 
 #include "jsobjinlines.h"
 
 using namespace js;
 
-Class js::ModuleClass = {
+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,
@@ -32,16 +32,16 @@ inline void
 Module::setScript(JSScript *script)
 {
     setReservedSlot(SCRIPT_SLOT, PrivateValue(script));
 }
 
 Module *
 Module::create(JSContext *cx, HandleAtom atom)
 {
-    RootedObject object(cx, NewBuiltinClassInstance(cx, &ModuleClass));
+    RootedObject object(cx, NewBuiltinClassInstance(cx, &class_));
     if (!object)
         return NULL;
-    RootedModule module(cx, &object->asModule());
+    RootedModule module(cx, &object->as<Module>());
     module->setAtom(atom);
     module->setScript(NULL);
     return module;
 }
--- a/js/src/builtin/Module.h
+++ b/js/src/builtin/Module.h
@@ -18,16 +18,18 @@ class Module : public JSObject {
     JSAtom *atom() {
         return &getReservedSlot(ATOM_SLOT).toString()->asAtom();
     };
 
     JSScript *script() {
         return (JSScript *) getReservedSlot(SCRIPT_SLOT).toPrivate();
     }
 
+    static 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/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -806,17 +806,17 @@ ObjectBox::asFunctionBox()
     return static_cast<FunctionBox *>(this);
 }
 
 ObjectBox::ObjectBox(Module *module, ObjectBox* traceLink)
   : object(module),
     traceLink(traceLink),
     emitLink(NULL)
 {
-    JS_ASSERT(object->isModule());
+    JS_ASSERT(object->is<Module>());
 }
 
 void
 ObjectBox::trace(JSTracer *trc)
 {
     ObjectBox *box = this;
     while (box) {
         MarkObjectRoot(trc, &box->object, "parser.object");
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef ParseNode_h__
 #define ParseNode_h__
 
 #include "mozilla/Attributes.h"
 
 #include "jsscript.h"
-
+#include "builtin/Module.h"
 #include "frontend/TokenStream.h"
 
 namespace js {
 namespace frontend {
 
 template <typename ParseHandler>
 struct ParseContext;
 
@@ -1355,17 +1355,17 @@ ParseNode::isConstant()
 }
 
 class ObjectBox
 {
   public:
     JSObject *object;
 
     ObjectBox(JSObject *object, ObjectBox *traceLink);
-    bool isModuleBox() { return object->isModule(); }
+    bool isModuleBox() { return object->is<Module>(); }
     bool isFunctionBox() { return object->isFunction(); }
     ModuleBox *asModuleBox();
     FunctionBox *asFunctionBox();
     void trace(JSTracer *trc);
 
   protected:
     friend struct CGObjectList;
 
--- a/js/src/frontend/SharedContext.h
+++ b/js/src/frontend/SharedContext.h
@@ -187,17 +187,17 @@ class GlobalSharedContext : public Share
 class ModuleBox : public ObjectBox, public SharedContext
 {
   public:
     Bindings bindings;
 
     ModuleBox(JSContext *cx, ObjectBox *traceListHead, Module *module,
               ParseContext<FullParseHandler> *pc);
     ObjectBox *toObjectBox() { return this; }
-    Module *module() const { return &object->asModule(); }
+    Module *module() const { return &object->as<Module>(); }
 };
 
 class FunctionBox : public ObjectBox, public SharedContext
 {
   public:
     Bindings        bindings;               /* bindings for this function */
     uint32_t        bufStart;
     uint32_t        bufEnd;
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -212,17 +212,16 @@ extern Class DataViewClass;
 extern Class DateClass;
 extern Class ErrorClass;
 extern Class ElementIteratorClass;
 extern Class GeneratorClass;
 extern Class IntlClass;
 extern Class JSONClass;
 extern Class MapIteratorClass;
 extern Class MathClass;
-extern Class ModuleClass;
 extern Class NumberClass;
 extern Class NormalArgumentsObjectClass;
 extern Class ObjectClass;
 extern Class ProxyClass;
 extern Class RegExpClass;
 extern Class RegExpStaticsClass;
 extern Class SetIteratorClass;
 extern Class ScriptSourceClass;
@@ -239,17 +238,16 @@ class BooleanObject;
 class ClonedBlockObject;
 class DataViewObject;
 class DebugScopeObject;
 class DeclEnvObject;
 class ElementIteratorObject;
 class GlobalObject;
 class MapObject;
 class MapIteratorObject;
-class Module;
 class NestedScopeObject;
 class NewObjectCache;
 class NormalArgumentsObject;
 class NumberObject;
 class PropertyIteratorObject;
 class ScopeObject;
 class SetObject;
 class SetIteratorObject;
@@ -962,29 +960,43 @@ class JSObject : public js::ObjectImpl
      * js::ObjectClassIs).
      *
      * SpiderMonkey has not been completely switched to the isX/asX/XObject
      * pattern so in some cases there is no XObject class and the engine
      * instead pokes directly at reserved slots and getPrivate. In such cases,
      * consider adding the missing XObject class.
      */
 
+    template <class T>
+    inline bool is() const { return getClass() == &T::class_; }
+
+    template <class T>
+    T &as() {
+        JS_ASSERT(is<T>());
+        return *static_cast<T *>(this);
+    }
+
+    template <class T>
+    const T &as() const {
+        JS_ASSERT(is<T>());
+        return *static_cast<const T *>(this);
+    }
+
     /* Direct subtypes of JSObject: */
     inline bool isArray()            const { return hasClass(&js::ArrayClass); }
     inline bool isArguments()        const { return isNormalArguments() || isStrictArguments(); }
     inline bool isArrayBuffer()      const { return hasClass(&js::ArrayBufferClass); }
     inline bool isDataView()         const { return hasClass(&js::DataViewClass); }
     inline bool isDate()             const { return hasClass(&js::DateClass); }
     inline bool isElementIterator()  const { return hasClass(&js::ElementIteratorClass); }
     inline bool isError()            const { return hasClass(&js::ErrorClass); }
     inline bool isFunction()         const { return hasClass(&js::FunctionClass); }
     inline bool isGenerator()        const { return hasClass(&js::GeneratorClass); }
     inline bool isGlobal()           const;
     inline bool isMapIterator()      const { return hasClass(&js::MapIteratorClass); }
-    inline bool isModule()           const { return hasClass(&js::ModuleClass); }
     inline bool isObject()           const { return hasClass(&js::ObjectClass); }
     inline bool isPrimitive()        const { return isNumber() || isString() || isBoolean(); }
     inline bool isPropertyIterator() const;
     using js::ObjectImpl::isProxy;
     inline bool isRegExp()           const { return hasClass(&js::RegExpClass); }
     inline bool isRegExpStatics()    const { return hasClass(&js::RegExpStaticsClass); }
     inline bool isScope()            const { return isCall() || isDeclEnv() || isNestedScope(); }
     inline bool isScriptSource()     const { return hasClass(&js::ScriptSourceClass); }
@@ -1025,20 +1037,16 @@ class JSObject : public js::ObjectImpl
     inline js::CallObject &asCall();
     inline js::ClonedBlockObject &asClonedBlock();
     inline js::DataViewObject &asDataView();
     inline js::DeclEnvObject &asDeclEnv();
     inline js::DebugScopeObject &asDebugScope();
     inline js::GlobalObject &asGlobal();
     inline js::MapObject &asMap();
     inline js::MapIteratorObject &asMapIterator();
-    js::Module &asModule() {
-        JS_ASSERT(isModule());
-        return *reinterpret_cast<js::Module *>(this);
-    }
     inline js::NestedScopeObject &asNestedScope();
     inline js::NormalArgumentsObject &asNormalArguments();
     inline js::NumberObject &asNumber();
     inline js::PropertyIteratorObject &asPropertyIterator();
     inline const js::PropertyIteratorObject &asPropertyIterator() const;
     inline js::RegExpObject &asRegExp();
     inline js::ScopeObject &asScope();
     inline js::SetObject &asSet();