Bug 1055472 - Part 6: Make the Number constructor properly subclassable. (r=Waldo)
☠☠ backed out by 4618d76a09f0 ☠ ☠
authorEric Faust <efaustbmo@gmail.com>
Fri, 13 Nov 2015 18:22:21 -0800
changeset 273136 a3eee2d8c90e7b83df1ef6a6793f99b66e55591c
parent 273135 b5e04101582ccc1b5dbd605fab0955c65ad7935b
child 273137 df80bd4dbb44217d9237509810b269ab67b5cf0b
push id68184
push userefaustbmo@gmail.com
push dateWed, 18 Nov 2015 22:11:26 +0000
treeherdermozilla-inbound@0389acea3fc7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersWaldo
bugs1055472
milestone45.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 1055472 - Part 6: Make the Number constructor properly subclassable. (r=Waldo)
js/src/jsnum.cpp
js/src/tests/ecma_6/Class/extendBuiltinConstructors.js
js/src/vm/NumberObject-inl.h
js/src/vm/NumberObject.h
--- a/js/src/jsnum.cpp
+++ b/js/src/jsnum.cpp
@@ -483,17 +483,21 @@ Number(JSContext* cx, unsigned argc, Val
         args.rval().set(args[0]);
     } else {
         args.rval().setInt32(0);
     }
 
     if (!isConstructing)
         return true;
 
-    JSObject* obj = NumberObject::create(cx, args.rval().toNumber());
+    RootedObject newTarget(cx, &args.newTarget().toObject());
+    RootedObject proto(cx);
+    if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
+        return false;
+    JSObject* obj = NumberObject::create(cx, args.rval().toNumber(), proto);
     if (!obj)
         return false;
     args.rval().setObject(*obj);
     return true;
 }
 
 MOZ_ALWAYS_INLINE bool
 IsNumber(HandleValue v)
--- a/js/src/tests/ecma_6/Class/extendBuiltinConstructors.js
+++ b/js/src/tests/ecma_6/Class/extendBuiltinConstructors.js
@@ -20,16 +20,17 @@ testBuiltin(Object);
 testBuiltin(Boolean);
 testBuiltin(Error);
 testBuiltin(EvalError);
 testBuiltin(RangeError);
 testBuiltin(ReferenceError);
 testBuiltin(SyntaxError);
 testBuiltin(TypeError);
 testBuiltin(URIError);
+testBuiltin(Number);
 
 `;
 
 if (classesEnabled())
     eval(test);
 
 if (typeof reportCompare === 'function')
     reportCompare(0,0,"OK");
--- a/js/src/vm/NumberObject-inl.h
+++ b/js/src/vm/NumberObject-inl.h
@@ -9,21 +9,20 @@
 
 #include "vm/NumberObject.h"
 
 #include "jsobjinlines.h"
 
 namespace js {
 
 inline NumberObject*
-NumberObject::create(JSContext* cx, double d)
+NumberObject::create(JSContext* cx, double d, HandleObject proto /* = nullptr */)
 {
-    JSObject* obj = NewBuiltinClassInstance(cx, &class_);
+    NumberObject* obj = NewObjectWithClassProto<NumberObject>(cx, proto);
     if (!obj)
         return nullptr;
-    NumberObject& numobj = obj->as<NumberObject>();
-    numobj.setPrimitiveValue(d);
-    return &numobj;
+    obj->setPrimitiveValue(d);
+    return obj;
 }
 
 } // namespace js
 
 #endif /* vm_NumberObject_inl_h */
--- a/js/src/vm/NumberObject.h
+++ b/js/src/vm/NumberObject.h
@@ -17,20 +17,21 @@ class NumberObject : public NativeObject
     static const unsigned PRIMITIVE_VALUE_SLOT = 0;
 
   public:
     static const unsigned RESERVED_SLOTS = 1;
 
     static const Class class_;
 
     /*
-     * Creates a new Number object boxing the given number.  The object's
-     * [[Prototype]] is determined from context.
+     * Creates a new Number object boxing the given number.
+     * If proto is nullptr, then Number.prototype will be used instead.
      */
-    static inline NumberObject* create(JSContext* cx, double d);
+    static inline NumberObject* create(JSContext* cx, double d,
+                                       HandleObject proto = nullptr);
 
     double unbox() const {
         return getFixedSlot(PRIMITIVE_VALUE_SLOT).toNumber();
     }
 
   private:
     inline void setPrimitiveValue(double d) {
         setFixedSlot(PRIMITIVE_VALUE_SLOT, NumberValue(d));