Bug 1020460 - Array.prototype.toSource should be generic. r=jorendorff
☠☠ backed out by 6502442e6133 ☠ ☠
authorBobby Holley <bobbyholley@gmail.com>
Fri, 06 Jun 2014 13:49:38 -0700
changeset 207638 eca7bdeb0c6e333669cbbe585fbc3de979762aba
parent 207637 9655784430622fdd44aa40c835d517bdd1a24548
child 207639 e2b9d289514f019a8c6f9ca1e8fe8ef928a771fe
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1020460
milestone32.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 1020460 - Array.prototype.toSource should be generic. r=jorendorff
js/src/jit-test/tests/basic/array-tosource.js
js/src/jit-test/tests/basic/testCrossCompartmentTransparency.js
js/src/jsarray.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/array-tosource.js
@@ -0,0 +1,8 @@
+load(libdir + 'asserts.js');
+
+assertEq(Array.prototype.toSource.call([1, 'hi']), '[1, "hi"]');
+assertEq(Array.prototype.toSource.call({1: 10, 0: 42, length: 2}), "[42, 10]");
+assertEq(Array.prototype.toSource.call({1: 10, 0: 42, length: 1}), "[42]");
+assertThrowsInstanceOf(() => Array.prototype.toSource.call("someString"), TypeError);
+assertThrowsInstanceOf(() => Array.prototype.toSource.call(42), TypeError);
+assertThrowsInstanceOf(() => Array.prototype.toSource.call(undefined), TypeError);
--- a/js/src/jit-test/tests/basic/testCrossCompartmentTransparency.js
+++ b/js/src/jit-test/tests/basic/testCrossCompartmentTransparency.js
@@ -51,17 +51,16 @@ function test(str, f) {
         f(proxy2);
     } catch (e) {
         assertEq(Object.prototype.toString.call(e), "[object Error]");
         threw = true;
     }
     assertEq(threw, true);
 }
 
-test("new Array(1,2,3)", function(a) Array.prototype.toSource.call(a));
 test("new Boolean(true)", function(b) Boolean.prototype.toSource.call(b));
 test("new Boolean(true)", function(b) Boolean.prototype.toString.call(b));
 test("new Boolean(true)", function(b) Boolean.prototype.valueOf.call(b));
 test("new Number(1)", function(n) Number.prototype.toSource.call(n));
 test("new Number(1)", function(n) Number.prototype.toString.call(n));
 test("new Number(1)", function(n) Number.prototype.valueOf.call(n));
 test("new Number(1)", function(n) Number.prototype.toFixed.call(n));
 test("new Number(1)", function(n) Number.prototype.toExponential.call(n));
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -845,26 +845,27 @@ AddLengthProperty(ExclusiveContext *cx, 
     JS_ASSERT(!obj->nativeLookup(cx, lengthId));
 
     return JSObject::addProperty(cx, obj, lengthId, array_length_getter, array_length_setter,
                                  SHAPE_INVALID_SLOT, JSPROP_PERMANENT | JSPROP_SHARED, 0,
                                  /* allowDictionary = */ false);
 }
 
 #if JS_HAS_TOSOURCE
-MOZ_ALWAYS_INLINE bool
-IsArray(HandleValue v)
+
+static bool
+array_toSource(JSContext *cx, unsigned argc, Value *vp)
 {
-    return v.isObject() && v.toObject().is<ArrayObject>();
-}
-
-MOZ_ALWAYS_INLINE bool
-array_toSource_impl(JSContext *cx, CallArgs args)
-{
-    JS_ASSERT(IsArray(args.thisv()));
+    JS_CHECK_RECURSION(cx, return false);
+    CallArgs args = CallArgsFromVp(argc, vp);
+
+    if (!args.thisv().isObject()) {
+        ReportIncompatible(cx, args);
+        return false;
+    }
 
     Rooted<JSObject*> obj(cx, &args.thisv().toObject());
     RootedValue elt(cx);
 
     AutoCycleDetector detector(cx, obj);
     if (!detector.init())
         return false;
 
@@ -920,23 +921,16 @@ array_toSource_impl(JSContext *cx, CallA
     JSString *str = sb.finishString();
     if (!str)
         return false;
 
     args.rval().setString(str);
     return true;
 }
 
-static bool
-array_toSource(JSContext *cx, unsigned argc, Value *vp)
-{
-    JS_CHECK_RECURSION(cx, return false);
-    CallArgs args = CallArgsFromVp(argc, vp);
-    return CallNonGenericMethod<IsArray, array_toSource_impl>(cx, args);
-}
 #endif
 
 struct EmptySeparatorOp
 {
     bool operator()(JSContext *, StringBuffer &sb) { return true; }
 };
 
 struct CharSeparatorOp