Diff
Modified: trunk/LayoutTests/ChangeLog (203100 => 203101)
--- trunk/LayoutTests/ChangeLog 2016-07-12 00:16:19 UTC (rev 203100)
+++ trunk/LayoutTests/ChangeLog 2016-07-12 00:57:35 UTC (rev 203101)
@@ -1,3 +1,15 @@
+2016-07-11 Benjamin Poulain <[email protected]>
+
+ [JSC] Array.from() and Array.of() try to build objects even if "this" is not a constructor
+ https://bugs.webkit.org/show_bug.cgi?id=159604
+
+ Reviewed by Yusuke Suzuki.
+
+ * js/array-from-expected.txt:
+ * js/array-of-expected.txt:
+ * js/script-tests/array-from.js:
+ * js/script-tests/array-of.js:
+
2016-07-11 Simon Fraser <[email protected]>
Deleting in a text input inside an iframe causes the page to scroll incorrectly
Modified: trunk/LayoutTests/js/array-from-expected.txt (203100 => 203101)
--- trunk/LayoutTests/js/array-from-expected.txt 2016-07-12 00:16:19 UTC (rev 203100)
+++ trunk/LayoutTests/js/array-from-expected.txt 2016-07-12 00:57:35 UTC (rev 203101)
@@ -67,6 +67,31 @@
Construction using Set object
-------
PASS Array.from(set) is ['zero', 'one', 'two']
+
+"this" is a constructor
+-------
+PASS Array.from.call(CustomConstructor, ['WebKit']).constructor is CustomConstructor
+PASS Object.getPrototypeOf(Array.from.call(CustomConstructor, ['WebKit'])) is CustomConstructor.prototype
+PASS Array.from.call(nonConstructor, ['WebKit']).length is 1
+PASS Array.from.call(nonConstructor, ['WebKit'])[0] is "WebKit"
+PASS Array.from.call(CustomConstructor, nonIterable).constructor is CustomConstructor
+PASS Object.getPrototypeOf(Array.from.call(CustomConstructor, nonIterable)) is CustomConstructor.prototype
+PASS Array.from.call(nonConstructor, nonIterable).length is 2
+PASS Array.from.call(nonConstructor, nonIterable)[0] is "one"
+PASS Array.from.call(nonConstructor, nonIterable)[1] is 2
+
+"this" is not a constructor
+-------
+PASS Array.from.call(nonConstructor, ['WebKit']).constructor is Array
+PASS Object.getPrototypeOf(Array.from.call(nonConstructor, ['WebKit'])) is Array.prototype
+PASS Array.from.call(nonConstructor, ['WebKit']).length is 1
+PASS Array.from.call(nonConstructor, ['WebKit'])[0] is "WebKit"
+PASS nonConstructorWasCalled is false
+PASS Array.from.call(nonConstructor, nonIterable).constructor is Array
+PASS Object.getPrototypeOf(Array.from.call(nonConstructor, nonIterable)) is Array.prototype
+PASS Array.from.call(nonConstructor, nonIterable).length is 2
+PASS Array.from.call(nonConstructor, nonIterable)[0] is "one"
+PASS Array.from.call(nonConstructor, nonIterable)[1] is 2
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/js/array-of-expected.txt (203100 => 203101)
--- trunk/LayoutTests/js/array-of-expected.txt 2016-07-12 00:16:19 UTC (rev 203100)
+++ trunk/LayoutTests/js/array-of-expected.txt 2016-07-12 00:57:35 UTC (rev 203101)
@@ -17,9 +17,16 @@
PASS x[1].length is 5
Check that a setter isn't called.
PASS Array.of(1, 2, 3) did not throw exception.
+"this" is a constructor
PASS Array.of.call(Foo, 'a', 'b', 'c') instanceof Foo is true
PASS Array.of.call(Foo, 'a', 'b', 'c').givenLength is 3
PASS var foo = Array.of.call(Foo, 'a', 'b', 'c'); [foo.length, foo[0], foo[1], foo[2]] is [3, 'a', 'b', 'c']
+"this" is not a constructor
+PASS Array.of.call(nonConstructor, Foo).constructor is Array
+PASS Object.getPrototypeOf(Array.of.call(nonConstructor, Foo)) is Array.prototype
+PASS Array.of.call(nonConstructor, Foo).length is 1
+PASS Array.of.call(nonConstructor, Foo)[0] is Foo
+PASS nonConstructorWasCalled is false
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/js/script-tests/array-from.js (203100 => 203101)
--- trunk/LayoutTests/js/script-tests/array-from.js 2016-07-12 00:16:19 UTC (rev 203100)
+++ trunk/LayoutTests/js/script-tests/array-from.js 2016-07-12 00:57:35 UTC (rev 203101)
@@ -100,3 +100,47 @@
set.add("one");
set.add("two");
shouldBe("Array.from(set)", "['zero', 'one', 'two']");
+
+section("\"this\" is a constructor");
+var CustomConstructor = function (length) { this.givenLength = length; };
+shouldBe("Array.from.call(CustomConstructor, ['WebKit']).constructor", "CustomConstructor");
+shouldBe("Object.getPrototypeOf(Array.from.call(CustomConstructor, ['WebKit']))", "CustomConstructor.prototype");
+shouldBe("Array.from.call(nonConstructor, ['WebKit']).length", "1");
+shouldBeEqualToString("Array.from.call(nonConstructor, ['WebKit'])[0]", "WebKit");
+
+var nonIterable = {
+ get 0() {
+ return "one";
+ },
+ get 1() {
+ return 2;
+ },
+ get 2() {
+ throw "ERROR: this should never be called";
+ },
+ get length() {
+ return 2;
+ }
+};
+
+shouldBe("Array.from.call(CustomConstructor, nonIterable).constructor", "CustomConstructor");
+shouldBe("Object.getPrototypeOf(Array.from.call(CustomConstructor, nonIterable))", "CustomConstructor.prototype");
+shouldBe("Array.from.call(nonConstructor, nonIterable).length", "2");
+shouldBeEqualToString("Array.from.call(nonConstructor, nonIterable)[0]", "one");
+shouldBe("Array.from.call(nonConstructor, nonIterable)[1]", "2");
+
+
+section("\"this\" is not a constructor");
+var nonConstructorWasCalled = false;
+var nonConstructor = () => { nonConstructorWasCalled = true; };
+shouldBe("Array.from.call(nonConstructor, ['WebKit']).constructor", "Array");
+shouldBe("Object.getPrototypeOf(Array.from.call(nonConstructor, ['WebKit']))", "Array.prototype");
+shouldBe("Array.from.call(nonConstructor, ['WebKit']).length", "1");
+shouldBeEqualToString("Array.from.call(nonConstructor, ['WebKit'])[0]", "WebKit");
+shouldBeFalse("nonConstructorWasCalled");
+
+shouldBe("Array.from.call(nonConstructor, nonIterable).constructor", "Array");
+shouldBe("Object.getPrototypeOf(Array.from.call(nonConstructor, nonIterable))", "Array.prototype");
+shouldBe("Array.from.call(nonConstructor, nonIterable).length", "2");
+shouldBeEqualToString("Array.from.call(nonConstructor, nonIterable)[0]", "one");
+shouldBe("Array.from.call(nonConstructor, nonIterable)[1]", "2");
Modified: trunk/LayoutTests/js/script-tests/array-of.js (203100 => 203101)
--- trunk/LayoutTests/js/script-tests/array-of.js 2016-07-12 00:16:19 UTC (rev 203100)
+++ trunk/LayoutTests/js/script-tests/array-of.js 2016-07-12 00:57:35 UTC (rev 203101)
@@ -25,7 +25,17 @@
shouldNotThrow("Array.of(1, 2, 3)");
+debug("\"this\" is a constructor");
var Foo = function FooBar(length) { this.givenLength = length; };
-shouldBeTrue("Array.of.call(Foo, 'a', 'b', 'c') instanceof Foo")
+shouldBeTrue("Array.of.call(Foo, 'a', 'b', 'c') instanceof Foo");
shouldBe("Array.of.call(Foo, 'a', 'b', 'c').givenLength", "3");
shouldBe("var foo = Array.of.call(Foo, 'a', 'b', 'c'); [foo.length, foo[0], foo[1], foo[2]]", "[3, 'a', 'b', 'c']");
+
+debug("\"this\" is not a constructor");
+var nonConstructorWasCalled = false;
+var nonConstructor = () => { nonConstructorWasCalled = true; };
+shouldBe("Array.of.call(nonConstructor, Foo).constructor", "Array");
+shouldBe("Object.getPrototypeOf(Array.of.call(nonConstructor, Foo))", "Array.prototype");
+shouldBe("Array.of.call(nonConstructor, Foo).length", "1");
+shouldBe("Array.of.call(nonConstructor, Foo)[0]", "Foo");
+shouldBeFalse("nonConstructorWasCalled");
Modified: trunk/Source/_javascript_Core/ChangeLog (203100 => 203101)
--- trunk/Source/_javascript_Core/ChangeLog 2016-07-12 00:16:19 UTC (rev 203100)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-07-12 00:57:35 UTC (rev 203101)
@@ -1,3 +1,17 @@
+2016-07-11 Benjamin Poulain <[email protected]>
+
+ [JSC] Array.from() and Array.of() try to build objects even if "this" is not a constructor
+ https://bugs.webkit.org/show_bug.cgi?id=159604
+
+ Reviewed by Yusuke Suzuki.
+
+ The spec says IsConstructor(), we were just checking if "this"
+ is any function.
+
+ * builtins/ArrayConstructor.js:
+ (of):
+ (from):
+
2016-07-11 Keith Miller <[email protected]>
defineProperty on a index of a TypedArray should throw if configurable
Modified: trunk/Source/_javascript_Core/builtins/ArrayConstructor.js (203100 => 203101)
--- trunk/Source/_javascript_Core/builtins/ArrayConstructor.js 2016-07-12 00:16:19 UTC (rev 203100)
+++ trunk/Source/_javascript_Core/builtins/ArrayConstructor.js 2016-07-12 00:57:35 UTC (rev 203101)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,8 +28,7 @@
"use strict";
var length = arguments.length;
- // TODO: Need isConstructor(this) instead of typeof "function" check.
- var array = typeof this === 'function' ? new this(length) : new @Array(length);
+ var array = @isConstructor(this) ? new this(length) : new @Array(length);
for (var k = 0; k < length; ++k)
@putByValDirect(array, k, arguments[k]);
array.length = length;
@@ -62,8 +61,7 @@
if (typeof iteratorMethod !== "function")
throw new @TypeError("Array.from requires that the property of the first argument, items[Symbol.iterator], when exists, be a function");
- // TODO: Need isConstructor(thisObj) instead of typeof "function" check.
- var result = (typeof thisObj === "function") ? @Object(new thisObj()) : [];
+ var result = @isConstructor(thisObj) ? new thisObj() : [];
var k = 0;
var iterator = iteratorMethod.@call(items);
@@ -89,8 +87,7 @@
var arrayLike = @Object(items);
var arrayLikeLength = @toLength(arrayLike.length);
- // TODO: Need isConstructor(thisObj) instead of typeof "function" check.
- var result = (typeof thisObj === "function") ? @Object(new thisObj(arrayLikeLength)) : new @Array(arrayLikeLength);
+ var result = @isConstructor(thisObj) ? new thisObj(arrayLikeLength) : new @Array(arrayLikeLength);
var k = 0;
while (k < arrayLikeLength) {