Bug 1055472 - Part 6: Make the Number constructor properly subclassable. (r=Waldo)
☠☠ backed out by 652bd59cdb51 ☠ ☠
authorEric Faust <efaustbmo@gmail.com>
Fri, 13 Nov 2015 18:22:21 -0800
changeset 273424 94135702e1b51d1811b0735c672f60227eac1503
parent 273423 1509efcfa6290ef8926f83ec8b04b945a891ef74
child 273425 65d962413c98659e3a06de96e481b845913bead4
push id29702
push usercbook@mozilla.com
push dateFri, 20 Nov 2015 12:13:22 +0000
treeherderautoland@ec628289d8b4 [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));