Bug 1055472 - Part 7: Make the Date constructor properly subclassable. (r=Waldo)
☠☠ backed out by 0f9b54b8ed53 ☠ ☠
authorEric Faust <efaustbmo@gmail.com>
Fri, 13 Nov 2015 18:22:21 -0800
changeset 272492 d3975d9482080dbbaa5603da90b41ccf15a6de8a
parent 272491 03d708347ebba969cdb94bdf3a9abf30c86e126b
child 272493 1e968e8a279a41ac5ec8b91c442750e68f5a57a4
push id67995
push userefaustbmo@gmail.com
push dateSat, 14 Nov 2015 02:22:43 +0000
treeherdermozilla-inbound@738e23a218c8 [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 7: Make the Date constructor properly subclassable. (r=Waldo)
js/src/jsdate.cpp
js/src/jsdate.h
js/src/tests/ecma_6/Class/extendBuiltinConstructors.js
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -3011,17 +3011,24 @@ static const JSFunctionSpec date_methods
     JS_FN(js_valueOf_str,        date_valueOf,            0,0),
     JS_SYM_FN(toPrimitive,       date_toPrimitive,        1,JSPROP_READONLY),
     JS_FS_END
 };
 
 static bool
 NewDateObject(JSContext* cx, const CallArgs& args, ClippedTime t)
 {
-    JSObject* obj = NewDateObjectMsec(cx, t);
+    MOZ_ASSERT(args.isConstructing());
+
+    RootedObject proto(cx);
+    RootedObject newTarget(cx, &args.newTarget().toObject());
+    if (!GetPrototypeFromConstructor(cx, newTarget, &proto))
+        return false;
+
+    JSObject* obj = NewDateObjectMsec(cx, t, proto);
     if (!obj)
         return false;
 
     args.rval().setObject(*obj);
     return true;
 }
 
 static bool
@@ -3255,19 +3262,19 @@ const Class DateObject::protoClass_ = {
         nullptr,
         nullptr,
         nullptr,
         ClassSpec::IsDelegated
     }
 };
 
 JSObject*
-js::NewDateObjectMsec(JSContext* cx, ClippedTime t)
+js::NewDateObjectMsec(JSContext* cx, ClippedTime t, HandleObject proto /* = nullptr */)
 {
-    JSObject* obj = NewBuiltinClassInstance(cx, &DateObject::class_);
+    JSObject* obj = NewObjectWithClassProto(cx, &DateObject::class_, proto);
     if (!obj)
         return nullptr;
     obj->as<DateObject>().setUTCTime(t);
     return obj;
 }
 
 JS_FRIEND_API(JSObject*)
 js::NewDateObject(JSContext* cx, int year, int mon, int mday,
--- a/js/src/jsdate.h
+++ b/js/src/jsdate.h
@@ -25,17 +25,17 @@ namespace js {
  * These functions provide a C interface to the date/time object
  */
 
 /*
  * Construct a new Date Object from a time value given in milliseconds UTC
  * since the epoch.
  */
 extern JSObject*
-NewDateObjectMsec(JSContext* cx, JS::ClippedTime t);
+NewDateObjectMsec(JSContext* cx, JS::ClippedTime t, JS::HandleObject proto = nullptr);
 
 /*
  * Construct a new Date Object from an exploded local time value.
  *
  * Assert that mon < 12 to help catch off-by-one user errors, which are common
  * due to the 0-based month numbering copied into JS from Java (java.util.Date
  * in 1995).
  */
--- a/js/src/tests/ecma_6/Class/extendBuiltinConstructors.js
+++ b/js/src/tests/ecma_6/Class/extendBuiltinConstructors.js
@@ -1,19 +1,19 @@
 var test = `
 
-function testBuiltin(builtin) {
+function testBuiltin(builtin, ...args) {
     class inst extends builtin {
-        constructor() {
-            super();
+        constructor(...args) {
+            super(...args);
             this.called = true;
         }
     }
 
-    let instance = new inst();
+    let instance = new inst(...args);
     assertEq(instance instanceof inst, true);
     assertEq(instance instanceof builtin, true);
     assertEq(instance.called, true);
 }
 
 
 testBuiltin(Function);
 testBuiltin(Object);
@@ -21,16 +21,19 @@ testBuiltin(Boolean);
 testBuiltin(Error);
 testBuiltin(EvalError);
 testBuiltin(RangeError);
 testBuiltin(ReferenceError);
 testBuiltin(SyntaxError);
 testBuiltin(TypeError);
 testBuiltin(URIError);
 testBuiltin(Number);
+testBuiltin(Date);
+testBuiltin(Date, 5);
+testBuiltin(Date, 5, 10);
 
 `;
 
 if (classesEnabled())
     eval(test);
 
 if (typeof reportCompare === 'function')
     reportCompare(0,0,"OK");