Backed out changeset e9a4931b119c (bug 861219)
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 12 May 2015 12:27:20 +0200
changeset 243531 4ce4fc16203d07c9dbc1adab39939585d3f62454
parent 243530 70244d662f4f262176fe05b2499a9e657d271a76
child 243532 4071627f11d316615f9c0ad80776d33f2ea5c87a
push id28741
push userkwierso@gmail.com
push dateTue, 12 May 2015 23:24:40 +0000
treeherdermozilla-central@d476776d920d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs861219
milestone40.0a1
backs oute9a4931b119cde54d7af98e693a82bc29bd96b86
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
Backed out changeset e9a4931b119c (bug 861219)
browser/devtools/webconsole/test/browser_webconsole_output_05.js
js/src/jit-test/tests/auto-regress/bug771946.js
js/src/jit-test/tests/basic/testCrossCompartmentTransparency.js
js/src/jsdate.cpp
js/src/tests/ecma/Date/15.9.5.2-2-n.js
js/src/tests/ecma/Date/15.9.5.js
js/src/tests/ecma/extensions/15.9.5.js
js/src/tests/ecma_2/Exceptions/date-001.js
js/src/tests/ecma_5/misc/builtin-methods-reject-null-undefined-this.js
js/src/tests/ecma_6/Date/browser.js
js/src/tests/ecma_6/Date/prototype-is-not-a-date.js
js/src/tests/ecma_6/Date/toString-generic.js
js/src/tests/js1_4/Regress/date-001-n.js
js/src/vm/DateObject.h
js/xpconnect/tests/unit/test_bug809652.js
toolkit/devtools/server/actors/script.js
--- a/browser/devtools/webconsole/test/browser_webconsole_output_05.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_05.js
@@ -59,20 +59,20 @@ let inputTests = [
     printOutput: "Invalid Date",
     inspectable: true,
     variablesViewLabel: "Invalid Date",
   },
 
   // 7
   {
     input: "Date.prototype",
-    output: /Object \{.*\}/,
+    output: "Date",
     printOutput: "Invalid Date",
     inspectable: true,
-    variablesViewLabel: "Object",
+    variablesViewLabel: "Date",
   },
 
   // 8
   {
     input: "new Number(43)",
     output: "43",
     inspectable: true,
   },
--- a/js/src/jit-test/tests/auto-regress/bug771946.js
+++ b/js/src/jit-test/tests/auto-regress/bug771946.js
@@ -1,4 +1,4 @@
 // Binary: cache/js-dbg-64-221f1a184f67-linux
 // Flags:
 //
-new Date().setFullYear(Math.cos(1))
+Date.prototype.setFullYear(Math.cos(1))
--- a/js/src/jit-test/tests/basic/testCrossCompartmentTransparency.js
+++ b/js/src/jit-test/tests/basic/testCrossCompartmentTransparency.js
@@ -10,55 +10,55 @@ var proxyStr = "Proxy.create(           
 "    defineProperty: () =>assertEq(true,false),            "+
 "    delete: () =>assertEq(true,false),                    "+
 "    fix: () =>assertEq(true,false), },                    "+
 "  Object.prototype                                        "+
 ");                                                        ";
 var proxy1 = g1.eval(proxyStr);
 var proxy2 = g2.eval(proxyStr);
 
-function test(str, f, isGeneric = false) {
+function test(str, f) {
     "use strict";
 
     var x = f(eval(str));
     assertEq(x, f(g1.eval(str)));
     assertEq(x, f(g2.eval(str)));
 
     var threw = false;
     try {
         f(g1.eval("new Object()"));
     } catch (e) {
         assertEq(Object.prototype.toString.call(e), "[object Error]");
         threw = true;
     }
-    assertEq(threw, !isGeneric);
+    assertEq(threw, true);
     threw = false;
     try {
         f(g2.eval("new Object()"));
     } catch (e) {
         assertEq(Object.prototype.toString.call(e), "[object Error]");
         threw = true;
     }
-    assertEq(threw, !isGeneric);
+    assertEq(threw, true);
     threw = false;
     try {
         f(proxy1);
     } catch (e) {
         assertEq(Object.prototype.toString.call(e), "[object Error]");
         threw = true;
     }
-    assertEq(threw, !isGeneric);
+    assertEq(threw, true);
     threw = false;
     try {
         f(proxy2);
     } catch (e) {
         assertEq(Object.prototype.toString.call(e), "[object Error]");
         threw = true;
     }
-    assertEq(threw, !isGeneric);
+    assertEq(threw, true);
 }
 
 test("new Boolean(true)", b => Boolean.prototype.toSource.call(b));
 test("new Boolean(true)", b => Boolean.prototype.toString.call(b));
 test("new Boolean(true)", b => Boolean.prototype.valueOf.call(b));
 test("new Number(1)", n => Number.prototype.toSource.call(n));
 test("new Number(1)", n => Number.prototype.toString.call(n));
 test("new Number(1)", n => Number.prototype.valueOf.call(n));
@@ -148,12 +148,12 @@ test("new Date()", d => justDontThrow(Da
 test("new Date()", d => justDontThrow(Date.prototype.toISOString.call(d)));
 test("new Date()", d => justDontThrow(Date.prototype.toLocaleString.call(d)));
 test("new Date()", d => justDontThrow(Date.prototype.toLocaleDateString.call(d)));
 test("new Date()", d => justDontThrow(Date.prototype.toLocaleTimeString.call(d)));
 test("new Date()", d => justDontThrow(Date.prototype.toLocaleFormat.call(d)));
 test("new Date()", d => justDontThrow(Date.prototype.toTimeString.call(d)));
 test("new Date()", d => justDontThrow(Date.prototype.toDateString.call(d)));
 test("new Date()", d => justDontThrow(Date.prototype.toSource.call(d)));
-test("new Date()", d => justDontThrow(Date.prototype.toString.call(d)), true);
+test("new Date()", d => justDontThrow(Date.prototype.toString.call(d)));
 test("new Date()", d => justDontThrow(Date.prototype.valueOf.call(d)));
 
 throw "done";
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -2864,36 +2864,28 @@ date_toSource_impl(JSContext* cx, CallAr
 static bool
 date_toSource(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     return CallNonGenericMethod<IsDate, date_toSource_impl>(cx, args);
 }
 #endif
 
-// ES6 final draft 20.3.4.41.
+MOZ_ALWAYS_INLINE bool
+date_toString_impl(JSContext* cx, CallArgs args)
+{
+    return date_format(cx, args.thisv().toObject().as<DateObject>().UTCTime().toNumber(),
+                       FORMATSPEC_FULL, args.rval());
+}
+
 static bool
 date_toString(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
-    // Step 2.a. (reordered)
-    double tv = GenericNaN();
-    if (args.thisv().isObject()) {
-        // Step 1.
-        RootedObject obj(cx, &args.thisv().toObject());
-        // Step 2.
-        if (ObjectClassIs(obj, ESClass_Date, cx)) {
-            // Step 3.a.
-            RootedValue unboxed(cx);
-            Unbox(cx, obj, &unboxed);
-            tv = unboxed.toNumber();
-        }
-    }
-    // Step 4.
-    return date_format(cx, tv, FORMATSPEC_FULL, args.rval());
+    return CallNonGenericMethod<IsDate, date_toString_impl>(cx, args);
 }
 
 MOZ_ALWAYS_INLINE bool
 date_valueOf_impl(JSContext* cx, CallArgs args)
 {
     Rooted<DateObject*> dateObj(cx, &args.thisv().toObject().as<DateObject>());
     args.rval().set(dateObj->UTCTime());
     return true;
@@ -3122,35 +3114,30 @@ js::DateConstructor(JSContext* cx, unsig
         return DateNoArguments(cx, args);
 
     if (args.length() == 1)
         return DateOneArgument(cx, args);
 
     return DateMultipleArguments(cx, args);
 }
 
-// ES6 final draft 20.3.4.
-static JSObject*
-CreateDatePrototype(JSContext* cx, JSProtoKey key)
-{
-    return cx->global()->createBlankPrototype(cx, &DateObject::protoClass_);
-}
-
 static bool
 FinishDateClassInit(JSContext* cx, HandleObject ctor, HandleObject proto)
 {
+    proto->as<DateObject>().setUTCTime(ClippedTime::NaN());
+
     /*
      * Date.prototype.toGMTString has the same initial value as
      * Date.prototype.toUTCString.
      */
     RootedValue toUTCStringFun(cx);
     RootedId toUTCStringId(cx, NameToId(cx->names().toUTCString));
     RootedId toGMTStringId(cx, NameToId(cx->names().toGMTString));
-    return NativeGetProperty(cx, proto.as<NativeObject>(), toUTCStringId, &toUTCStringFun) &&
-           NativeDefineProperty(cx, proto.as<NativeObject>(), toGMTStringId, toUTCStringFun,
+    return NativeGetProperty(cx, proto.as<DateObject>(), toUTCStringId, &toUTCStringFun) &&
+           NativeDefineProperty(cx, proto.as<DateObject>(), toGMTStringId, toUTCStringFun,
                                 nullptr, nullptr, 0);
 }
 
 const Class DateObject::class_ = {
     js_Date_str,
     JSCLASS_HAS_RESERVED_SLOTS(RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
     nullptr, /* addProperty */
@@ -3163,46 +3150,25 @@ const Class DateObject::class_ = {
     date_convert,
     nullptr, /* finalize */
     nullptr, /* call */
     nullptr, /* hasInstance */
     nullptr, /* construct */
     nullptr, /* trace */
     {
         GenericCreateConstructor<DateConstructor, 7, gc::AllocKind::FUNCTION>,
-        CreateDatePrototype,
+        GenericCreatePrototype,
         date_static_methods,
         nullptr,
         date_methods,
         nullptr,
         FinishDateClassInit
     }
 };
 
-const Class DateObject::protoClass_ = {
-    js_Object_str,
-    JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
-    nullptr, /* addProperty */
-    nullptr, /* delProperty */
-    nullptr, /* getProperty */
-    nullptr, /* setProperty */
-    nullptr, /* enumerate */
-    nullptr, /* resolve */
-    nullptr, /* mayResolve */
-    nullptr, /* convert */
-    nullptr, /* finalize */
-    nullptr, /* call */
-    nullptr, /* hasInstance */
-    nullptr, /* construct */
-    nullptr, /* trace  */
-    {
-        DELEGATED_CLASSSPEC(&DateObject::class_.spec)
-    }
-};
-
 JSObject*
 js::NewDateObjectMsec(JSContext* cx, ClippedTime t)
 {
     JSObject* obj = NewBuiltinClassInstance(cx, &DateObject::class_);
     if (!obj)
         return nullptr;
     obj->as<DateObject>().setUTCTime(t);
     return obj;
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma/Date/15.9.5.2-2-n.js
@@ -0,0 +1,50 @@
+/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+/**
+   File Name:          15.9.5.2-2.js
+   ECMA Section:       15.9.5.2 Date.prototype.toString
+   Description:
+   This function returns a string value. The contents of the string are
+   implementation dependent, but are intended to represent the Date in a
+   convenient, human-readable form in the current time zone.
+
+   The toString function is not generic; it generates a runtime error if its
+   this value is not a Date object. Therefore it cannot be transferred to
+   other kinds of objects for use as a method.
+
+
+   This verifies that calling toString on an object that is not a string
+   generates a runtime error.
+
+   Author:             christine@netscape.com
+   Date:               12 november 1997
+*/
+
+var SECTION = "15.9.5.2-2";
+var VERSION = "ECMA_1";
+startTest();
+var TITLE   = "Date.prototype.toString";
+
+writeHeaderToLog( SECTION + " "+ TITLE);
+
+var OBJ = new MyObject( new Date(0) );
+
+DESCRIPTION = "var OBJ = new MyObject( new Date(0) ); OBJ.toString()";
+EXPECTED = "error";
+
+new TestCase( SECTION,
+	      "var OBJ = new MyObject( new Date(0) ); OBJ.toString()",
+	      "error",
+	      eval("OBJ.toString()") );
+test();
+
+function MyObject( value ) {
+  this.value = value;
+  this.valueOf = new Function( "return this.value" );
+  this.toString = Date.prototype.toString;
+  return this;
+}
--- a/js/src/tests/ecma/Date/15.9.5.js
+++ b/js/src/tests/ecma/Date/15.9.5.js
@@ -34,19 +34,16 @@ var TITLE   = "Properties of the Date Pr
 
 writeHeaderToLog( SECTION + " "+ TITLE);
 
 
 Date.prototype.getClass = Object.prototype.toString;
 
 new TestCase( SECTION,
 	      "Date.prototype.getClass",
-	      "[object Object]",
+	      "[object Date]",
 	      Date.prototype.getClass() );
 new TestCase( SECTION,
 	      "Date.prototype.valueOf()",
-	      "TypeError",
-	      (function() { try { Date.prototype.valueOf() } catch (e) { return e.constructor.name; } })());
-new TestCase( SECTION,
-          "Date.prototype.__proto__ == Object.prototype",
-          true,
-          Date.prototype.__proto__ == Object.prototype );
+	      NaN,
+	      Date.prototype.valueOf() );
 test();
+
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma/extensions/15.9.5.js
@@ -0,0 +1,42 @@
+/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+/**
+   File Name:          15.9.5.js
+   ECMA Section:       15.9.5 Properties of the Date prototype object
+   Description:
+
+   The Date prototype object is itself a Date object (its [[Class]] is
+   "Date") whose value is NaN.
+
+   The value of the internal [[Prototype]] property of the Date prototype
+   object is the Object prototype object (15.2.3.1).
+
+   In following descriptions of functions that are properties of the Date
+   prototype object, the phrase "this Date object" refers to the object that
+   is the this value for the invocation of the function; it is an error if
+   this does not refer to an object for which the value of the internal
+   [[Class]] property is "Date". Also, the phrase "this time value" refers
+   to the number value for the time represented by this Date object, that is,
+   the value of the internal [[Value]] property of this Date object.
+
+   Author:             christine@netscape.com
+   Date:               12 november 1997
+*/
+
+var SECTION = "15.9.5";
+var VERSION = "ECMA_1";
+startTest();
+var TITLE   = "Properties of the Date Prototype Object";
+
+writeHeaderToLog( SECTION + " "+ TITLE);
+
+new TestCase( SECTION,
+	      "Date.prototype.__proto__ == Object.prototype",
+	      true,
+	      Date.prototype.__proto__ == Object.prototype );
+test();
+
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_2/Exceptions/date-001.js
@@ -0,0 +1,60 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+/**
+   File Name:          date-001.js
+   Corresponds To:     15.9.5.2-2.js
+   ECMA Section:       15.9.5.2 Date.prototype.toString
+   Description:
+   This function returns a string value. The contents of the string are
+   implementation dependent, but are intended to represent the Date in a
+   convenient, human-readable form in the current time zone.
+
+   The toString function is not generic; it generates a runtime error if its
+   this value is not a Date object. Therefore it cannot be transferred to
+   other kinds of objects for use as a method.
+
+
+   This verifies that calling toString on an object that is not a string
+   generates a runtime error.
+
+   Author:             christine@netscape.com
+   Date:               12 november 1997
+*/
+var SECTION = "date-001";
+var VERSION = "JS1_4";
+var TITLE   = "Date.prototype.toString";
+
+startTest();
+writeHeaderToLog( SECTION + " "+ TITLE);
+
+var result = "Failed";
+var exception = "No exception thrown";
+var expect = "Passed";
+
+try {
+  var OBJ = new MyObject( new Date(0) );
+  result = OBJ.toString();
+} catch ( e ) {
+  result = expect;
+  exception = e.toString();
+}
+
+new TestCase(
+  SECTION,
+  "OBJECT = new MyObject( new Date(0)) ; result = OBJ.toString()" +
+  " (threw " + exception +")",
+  expect,
+  result );
+
+test();
+
+function MyObject( value ) {
+  this.value = value;
+  this.valueOf = new Function( "return this.value" );
+  this.toString = Date.prototype.toString;
+  return this;
+}
--- a/js/src/tests/ecma_5/misc/builtin-methods-reject-null-undefined-this.js
+++ b/js/src/tests/ecma_5/misc/builtin-methods-reject-null-undefined-this.js
@@ -54,17 +54,17 @@ var ClassToMethodMap =
               /*
                * toFixed doesn't *immediately* test |this| for number or
                * Number-ness, but because the ToInteger(void 0) which arguably
                * precedes it in the toFixed algorithm won't throw in this test,
                * we don't need to specially test it.
                */
               "toFixed",
               "toExponential", "toPrecision"],
-    Date:    ["toDateString", "toTimeString", "toLocaleString",
+    Date:    ["toString", "toDateString", "toTimeString", "toLocaleString",
               "toLocaleDateString", "toLocaleTimeString", "valueOf", "getTime",
               "getFullYear", "getUTCFullYear", "getMonth", "getUTCMonth",
               "getDate", "getUTCDate", "getDay", "getUTCDay", "getHours",
               "getUTCHours", "getMinutes", "getUTCMinutes", "getSeconds",
               "getUTCSeconds", "getMilliseconds", "getUTCMilliseconds",
               /*
                * toFixed doesn't *immediately* test |this| for number or
                * Number-ness, but because the TimeClip(ToNumber(void 0)) which
deleted file mode 100644
deleted file mode 100644
--- a/js/src/tests/ecma_6/Date/prototype-is-not-a-date.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/licenses/publicdomain/
- */
-
-var BUGNUMBER = 861219;
-var summary = "Date.prototype isn't an instance of Date";
-
-print(BUGNUMBER + ": " + summary);
-
-assertEq(Date.prototype instanceof Date, false);
-assertEq(Date.prototype.__proto__, Object.prototype);
-
-if (typeof reportCompare === "function")
-  reportCompare(true, true);
deleted file mode 100644
--- a/js/src/tests/ecma_6/Date/toString-generic.js
+++ /dev/null
@@ -1,13 +0,0 @@
-var BUGNUMBER = 861219;
-var summary = 'Date.prototype.toString is a generic function';
-
-print(BUGNUMBER + ": " + summary);
-
-for (var thisValue of [null, undefined, 0, 1.2, true, false, "foo", Symbol.iterator,
-                       {}, [], /foo/, Date.prototype, new Proxy(new Date(), {})])
-{
-  assertEq(Date.prototype.toString.call(thisValue), "Invalid Date");
-}
-
-if (typeof reportCompare === "function")
-  reportCompare(true, true);
new file mode 100644
--- /dev/null
+++ b/js/src/tests/js1_4/Regress/date-001-n.js
@@ -0,0 +1,42 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+/**
+ *  File Name:          date-001-n.js
+ *  Description:
+ *
+ *  http://scopus.mcom.com/bugsplat/show_bug.cgi?id=299903
+ *
+ *  Author:             christine@netscape.com
+ *  Date:               11 August 1998
+ */
+var SECTION = "date-001-n.js";
+var VERSION = "JS1_4";
+var TITLE   = "Regression test case for 299903";
+var BUGNUMBER="299903";
+
+startTest();
+
+writeHeaderToLog( SECTION + " "+ TITLE);
+
+function MyDate() {
+  this.foo = "bar";
+}
+MyDate.prototype = new Date();
+
+DESCRIPTION =
+  "function MyDate() { this.foo = \"bar\"; }; MyDate.prototype = new Date(); new MyDate().toString()";
+EXPECTED = "error";
+
+new TestCase(
+  SECTION,
+  "function MyDate() { this.foo = \"bar\"; }; "+
+  "MyDate.prototype = new Date(); " +
+  "new MyDate().toString()",
+  "error",
+  new MyDate().toString() );
+
+test();
--- a/js/src/vm/DateObject.h
+++ b/js/src/vm/DateObject.h
@@ -36,17 +36,16 @@ class DateObject : public NativeObject
     static const uint32_t LOCAL_HOURS_SLOT   = COMPONENTS_START_SLOT + 5;
     static const uint32_t LOCAL_MINUTES_SLOT = COMPONENTS_START_SLOT + 6;
     static const uint32_t LOCAL_SECONDS_SLOT = COMPONENTS_START_SLOT + 7;
 
     static const uint32_t RESERVED_SLOTS = LOCAL_SECONDS_SLOT + 1;
 
   public:
     static const Class class_;
-    static const Class protoClass_;
 
     inline const js::Value& UTCTime() const {
         return getFixedSlot(UTC_TIME_SLOT);
     }
 
     // Set UTC time to a given time and invalidate cached local time.
     void setUTCTime(JS::ClippedTime t);
     void setUTCTime(JS::ClippedTime t, MutableHandleValue vp);
--- a/js/xpconnect/tests/unit/test_bug809652.js
+++ b/js/xpconnect/tests/unit/test_bug809652.js
@@ -35,16 +35,17 @@ function run_test() {
   checkThrows("ArrayBuffer.prototype.__lookupGetter__('byteLength').call(ab);", sb);
   checkThrows("ArrayBuffer.prototype.slice.call(ab, 0);", sb);
   checkThrows("DataView.prototype.getInt8.call(dv, 0);", sb);
 
   /* Now that Date is on Xrays, these should all throw. */
   checkThrows("Date.prototype.getYear.call(d)", sb);
   checkThrows("Date.prototype.valueOf.call(d)", sb);
   checkThrows("d.valueOf()", sb);
+  checkThrows("Date.prototype.toString.call(d)", sb);
   checkThrows("d.toString()", sb);
 
   /* Typed arrays. */
   function testForTypedArray(t) {
     sb.curr = t;
     sb.currName = t.constructor.name;
     checkThrows("this[currName].prototype.subarray.call(curr, 0)[0]", sb);
     checkThrows("(new this[currName]).__lookupGetter__('length').call(curr)", sb);
--- a/toolkit/devtools/server/actors/script.js
+++ b/toolkit/devtools/server/actors/script.js
@@ -3860,16 +3860,20 @@ DebuggerServer.ObjectActorPreviewers = {
     }
 
     let str = RegExp.prototype.toString.call(obj.unsafeDereference());
     aGrip.displayString = threadActor.createValueGrip(str);
     return true;
   }],
 
   Date: [function({obj, threadActor}, aGrip) {
+    if (!obj.proto || obj.proto.class != "Date") {
+      return false;
+    }
+
     let time = Date.prototype.getTime.call(obj.unsafeDereference());
 
     aGrip.preview = {
       timestamp: threadActor.createValueGrip(time),
     };
     return true;
   }],