Bug 1595745 - Part 1: Change Boolean to use ClassSpec. r=mgaudet
☠☠ backed out by ec8cad689121 ☠ ☠
authorAndré Bargull <andre.bargull@gmail.com>
Fri, 15 Nov 2019 14:59:59 +0000
changeset 502195 f082e5173ed480d3461749eff791207458c72b5e
parent 502194 da61ebbdb3a5d2991c508c610ef112aeb9d72c7f
child 502196 61d25028669b165048be8775429f79b1b136e13e
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmgaudet
bugs1595745
milestone72.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 1595745 - Part 1: Change Boolean to use ClassSpec. r=mgaudet Boolean.prototype is itself a Boolean object, so the ClassSpec needs to use a custom 'createPrototype' function to create and initialise the prototype object. Differential Revision: https://phabricator.services.mozilla.com/D52657
js/public/ProtoKey.h
js/src/builtin/Boolean.cpp
js/src/builtin/Boolean.h
js/src/vm/BooleanObject.h
--- a/js/public/ProtoKey.h
+++ b/js/public/ProtoKey.h
@@ -48,17 +48,17 @@
 #  define IF_TYPEDOBJ(REAL, IMAGINARY) IMAGINARY
 #endif
 
 #define JS_FOR_PROTOTYPES_(REAL, IMAGINARY, REAL_IF_INTL, REAL_IF_BDATA)     \
   IMAGINARY(Null, InitNullClass, dummy)                                      \
   REAL(Object, InitViaClassSpec, OCLASP(Plain))                              \
   REAL(Function, InitViaClassSpec, &JSFunction::class_)                      \
   REAL(Array, InitViaClassSpec, OCLASP(Array))                               \
-  REAL(Boolean, InitBooleanClass, OCLASP(Boolean))                           \
+  REAL(Boolean, InitViaClassSpec, OCLASP(Boolean))                           \
   REAL(JSON, InitJSONClass, CLASP(JSON))                                     \
   REAL(Date, InitViaClassSpec, OCLASP(Date))                                 \
   REAL(Math, InitMathClass, CLASP(Math))                                     \
   REAL(Number, InitNumberClass, OCLASP(Number))                              \
   REAL(String, InitStringClass, OCLASP(String))                              \
   REAL(RegExp, InitViaClassSpec, OCLASP(RegExp))                             \
   REAL(Error, InitViaClassSpec, ERROR_CLASP(JSEXN_ERR))                      \
   REAL(InternalError, InitViaClassSpec, ERROR_CLASP(JSEXN_INTERNALERR))      \
--- a/js/src/builtin/Boolean.cpp
+++ b/js/src/builtin/Boolean.cpp
@@ -24,17 +24,18 @@
 #include "vm/ProxyObject.h"
 
 #include "vm/BooleanObject-inl.h"
 
 using namespace js;
 
 const JSClass BooleanObject::class_ = {
     "Boolean",
-    JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean)};
+    JSCLASS_HAS_RESERVED_SLOTS(1) | JSCLASS_HAS_CACHED_PROTO(JSProto_Boolean),
+    JS_NULL_CLASS_OPS, &BooleanObject::classSpec_};
 
 MOZ_ALWAYS_INLINE bool IsBoolean(HandleValue v) {
   return v.isBoolean() || (v.isObject() && v.toObject().is<BooleanObject>());
 }
 
 MOZ_ALWAYS_INLINE bool bool_toSource_impl(JSContext* cx, const CallArgs& args) {
   HandleValue thisv = args.thisv();
   MOZ_ASSERT(IsBoolean(thisv));
@@ -114,49 +115,36 @@ static bool Boolean(JSContext* cx, unsig
     }
     args.rval().setObject(*obj);
   } else {
     args.rval().setBoolean(b);
   }
   return true;
 }
 
-JSObject* js::InitBooleanClass(JSContext* cx, Handle<GlobalObject*> global) {
-  Rooted<BooleanObject*> booleanProto(
-      cx, GlobalObject::createBlankPrototype<BooleanObject>(cx, global));
+JSObject* BooleanObject::createPrototype(JSContext* cx, JSProtoKey key) {
+  BooleanObject* booleanProto =
+      GlobalObject::createBlankPrototype<BooleanObject>(cx, cx->global());
   if (!booleanProto) {
     return nullptr;
   }
   booleanProto->setFixedSlot(BooleanObject::PRIMITIVE_VALUE_SLOT,
                              BooleanValue(false));
-
-  RootedFunction ctor(cx, GlobalObject::createConstructor(
-                              cx, Boolean, cx->names().Boolean, 1,
-                              gc::AllocKind::FUNCTION, &jit::JitInfo_Boolean));
-  if (!ctor) {
-    return nullptr;
-  }
-
-  if (!LinkConstructorAndPrototype(cx, ctor, booleanProto)) {
-    return nullptr;
-  }
-
-  if (!DefinePropertiesAndFunctions(cx, booleanProto, nullptr,
-                                    boolean_methods)) {
-    return nullptr;
-  }
-
-  if (!GlobalObject::initBuiltinConstructor(cx, global, JSProto_Boolean, ctor,
-                                            booleanProto)) {
-    return nullptr;
-  }
-
   return booleanProto;
 }
 
+const ClassSpec BooleanObject::classSpec_ = {
+    GenericCreateConstructor<Boolean, 1, gc::AllocKind::FUNCTION,
+                             &jit::JitInfo_Boolean>,
+    BooleanObject::createPrototype,
+    nullptr,
+    nullptr,
+    boolean_methods,
+    nullptr};
+
 JSString* js::BooleanToString(JSContext* cx, bool b) {
   return b ? cx->names().true_ : cx->names().false_;
 }
 
 JS_PUBLIC_API bool js::ToBooleanSlow(HandleValue v) {
   if (v.isString()) {
     return v.toString()->length() != 0;
   }
--- a/js/src/builtin/Boolean.h
+++ b/js/src/builtin/Boolean.h
@@ -6,22 +6,18 @@
 
 #ifndef builtin_Boolean_h
 #define builtin_Boolean_h
 
 /*
  * JS boolean interface.
  */
 
-#include "NamespaceImports.h"
+struct JSContext;
+class JSString;
 
 namespace js {
 
-class GlobalObject;
-
-extern JSObject* InitBooleanClass(JSContext* cx,
-                                  js::Handle<GlobalObject*> global);
-
 extern JSString* BooleanToString(JSContext* cx, bool b);
 
 }  // namespace js
 
 #endif /* builtin_Boolean_h */
--- a/js/src/vm/BooleanObject.h
+++ b/js/src/vm/BooleanObject.h
@@ -8,41 +8,39 @@
 #define vm_BooleanObject_h
 
 #include "builtin/Boolean.h"
 
 #include "vm/NativeObject.h"
 
 namespace js {
 
-class GlobalObject;
-
 class BooleanObject : public NativeObject {
   /* Stores this Boolean object's [[PrimitiveValue]]. */
   static const unsigned PRIMITIVE_VALUE_SLOT = 0;
 
+  static const ClassSpec classSpec_;
+
  public:
   static const unsigned RESERVED_SLOTS = 1;
 
   static const JSClass class_;
 
   /*
    * Creates a new Boolean object boxing the given primitive bool.
    * If proto is nullptr, the [[Prototype]] will default to Boolean.prototype.
    */
   static inline BooleanObject* create(JSContext* cx, bool b,
                                       HandleObject proto = nullptr);
 
   bool unbox() const { return getFixedSlot(PRIMITIVE_VALUE_SLOT).toBoolean(); }
 
  private:
+  static JSObject* createPrototype(JSContext* cx, JSProtoKey key);
+
   inline void setPrimitiveValue(bool b) {
     setFixedSlot(PRIMITIVE_VALUE_SLOT, BooleanValue(b));
   }
-
-  /* For access to init, as Boolean.prototype is special. */
-  friend JSObject* js::InitBooleanClass(JSContext* cx,
-                                        js::Handle<GlobalObject*> global);
 };
 
 }  // namespace js
 
 #endif /* vm_BooleanObject_h */