Diff
Modified: trunk/JSTests/ChangeLog (263943 => 263944)
--- trunk/JSTests/ChangeLog 2020-07-04 20:06:27 UTC (rev 263943)
+++ trunk/JSTests/ChangeLog 2020-07-04 20:06:54 UTC (rev 263944)
@@ -1,3 +1,15 @@
+2020-07-04 Alexey Shvayka <[email protected]>
+
+ %TypedArray%.prototype.{indexOf,lastIndexOf} are not spec-perfect
+ https://bugs.webkit.org/show_bug.cgi?id=213715
+
+ Reviewed by Yusuke Suzuki.
+
+ * microbenchmarks/array-prototype-indexOf-empty.js: Added.
+ * microbenchmarks/typed-array-indexOf-empty.js: Added.
+ * stress/array-indexof-tointeger-order.js: Added.
+ * test262/expectations.yaml: Mark 10 test cases as passing.
+
2020-07-03 Yusuke Suzuki <[email protected]>
[JSC] Promise should check whether a user-provided function is set by using `@isUndefinedOrNull`
Added: trunk/JSTests/microbenchmarks/array-prototype-indexOf-empty.js (0 => 263944)
--- trunk/JSTests/microbenchmarks/array-prototype-indexOf-empty.js (rev 0)
+++ trunk/JSTests/microbenchmarks/array-prototype-indexOf-empty.js 2020-07-04 20:06:54 UTC (rev 263944)
@@ -0,0 +1,5 @@
+var empty = [];
+noInline(Array.prototype.indexOf);
+
+for (var i = 0; i < 1e7; ++i)
+ empty.indexOf(1);
Added: trunk/JSTests/microbenchmarks/typed-array-indexOf-empty.js (0 => 263944)
--- trunk/JSTests/microbenchmarks/typed-array-indexOf-empty.js (rev 0)
+++ trunk/JSTests/microbenchmarks/typed-array-indexOf-empty.js 2020-07-04 20:06:54 UTC (rev 263944)
@@ -0,0 +1,5 @@
+var empty = new Int8Array();
+noInline(Int8Array.prototype.indexOf);
+
+for (var i = 0; i < 1e7; ++i)
+ empty.indexOf(1);
Added: trunk/JSTests/stress/array-indexof-tointeger-order.js (0 => 263944)
--- trunk/JSTests/stress/array-indexof-tointeger-order.js (rev 0)
+++ trunk/JSTests/stress/array-indexof-tointeger-order.js 2020-07-04 20:06:54 UTC (rev 263944)
@@ -0,0 +1,54 @@
+function assert(b) {
+ if (!b)
+ throw new Error("Bad assertion");
+}
+
+(function () {
+ function indexOfInt32(array, value, index)
+ {
+ return array.indexOf(value, index);
+ }
+ noInline(indexOfInt32);
+
+ function indexOfDouble(array, value, index)
+ {
+ return array.indexOf(value, index);
+ }
+ noInline(indexOfDouble);
+
+ function indexOfString(array, value, index)
+ {
+ return array.indexOf(value, index);
+ }
+ noInline(indexOfString);
+
+ var int32Array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
+ var doubleArray = [0, 1, 2, 3, 4.2, 5, 6, 7.33, 8, 9, 10.5];
+ var stringArray = ["cocoa", "cappuccino", "matcha", "rize"];
+
+ for (var i = 0; i < 1e5; ++i) {
+ assert(indexOfInt32(int32Array, 3, 2) === 3);
+ assert(indexOfDouble(doubleArray, 3, 1) === 3);
+ assert(indexOfString(stringArray, "cocoa", 0) === 0);
+ }
+
+ int32Array.length = 0;
+ doubleArray.splice(0);
+ while (stringArray.length) stringArray.pop();
+
+ assert($vm.indexingMode(int32Array) !== "ArrayWithUndecided");
+ assert($vm.indexingMode(doubleArray) !== "ArrayWithUndecided");
+ assert($vm.indexingMode(stringArray) !== "ArrayWithUndecided");
+
+ var fromIndex = {
+ get valueOf() {
+ throw new Error("fromIndex.valueOf");
+ },
+ };
+
+ for (var i = 0; i < 1e5; ++i) {
+ assert(indexOfInt32(int32Array, 3, fromIndex) === -1);
+ assert(indexOfDouble(doubleArray, 3, fromIndex) === -1);
+ assert(indexOfString(stringArray, "cocoa", fromIndex) === -1);
+ }
+}());
Modified: trunk/JSTests/test262/expectations.yaml (263943 => 263944)
--- trunk/JSTests/test262/expectations.yaml 2020-07-04 20:06:27 UTC (rev 263943)
+++ trunk/JSTests/test262/expectations.yaml 2020-07-04 20:06:54 UTC (rev 263944)
@@ -618,9 +618,6 @@
test/annexB/language/statements/function/default-parameters-emulates-undefined.js:
default: 'Test262Error: Expected SameValue(«undefined», «[object Function]») to be true'
strict mode: 'Test262Error: Expected SameValue(«undefined», «[object Function]») to be true'
-test/built-ins/Array/prototype/indexOf/length-zero-returns-minus-one.js:
- default: 'Test262Error: Length should be checked before ToInteger(fromIndex).'
- strict mode: 'Test262Error: Length should be checked before ToInteger(fromIndex).'
test/built-ins/ArrayBuffer/prototype/byteLength/detached-buffer.js:
default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
@@ -1440,18 +1437,6 @@
test/built-ins/TypedArray/prototype/filter/speciesctor-get-species-custom-ctor-length-throws.js:
default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
-test/built-ins/TypedArray/prototype/indexOf/length-zero-returns-minus-one.js:
- default: 'Test262Error: (Testing with Float64Array.)'
- strict mode: 'Test262Error: (Testing with Float64Array.)'
-test/built-ins/TypedArray/prototype/indexOf/no-arg.js:
- default: 'TypeError: Expected at least one argument (Testing with Float64Array.)'
- strict mode: 'TypeError: Expected at least one argument (Testing with Float64Array.)'
-test/built-ins/TypedArray/prototype/lastIndexOf/length-zero-returns-minus-one.js:
- default: 'Test262Error: (Testing with Float64Array.)'
- strict mode: 'Test262Error: (Testing with Float64Array.)'
-test/built-ins/TypedArray/prototype/lastIndexOf/no-arg.js:
- default: 'TypeError: Expected at least one argument (Testing with Float64Array.)'
- strict mode: 'TypeError: Expected at least one argument (Testing with Float64Array.)'
test/built-ins/TypedArray/prototype/map/speciesctor-get-ctor-returns-throws.js:
default: 'Test262Error: 42 Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
strict mode: 'Test262Error: 42 Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
Modified: trunk/Source/_javascript_Core/ChangeLog (263943 => 263944)
--- trunk/Source/_javascript_Core/ChangeLog 2020-07-04 20:06:27 UTC (rev 263943)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-07-04 20:06:54 UTC (rev 263944)
@@ -1,3 +1,33 @@
+2020-07-04 Alexey Shvayka <[email protected]>
+
+ %TypedArray%.prototype.{indexOf,lastIndexOf} are not spec-perfect
+ https://bugs.webkit.org/show_bug.cgi?id=213715
+
+ Reviewed by Yusuke Suzuki.
+
+ This patch:
+
+ 1. Implements step 3 of {Array,%TypedArray%}.prototype.indexOf [1] and
+ %TypedArray%.prototype.lastIndexOf [2] since it is observable when
+ second argument is an object with userland toString() or valueOf() method.
+ Advances provided microbenchmark by 100% for Array and by 25% for %TypedArray%.
+
+ 2. Removes argument count check from %TypedArray%.prototype.{indexOf,lastIndexOf},
+ allowing these methods to be invoked w/o arguments. The spec treats missing
+ arguments as `undefined`, always returning -1 for typed arrays.
+
+ Both changes align JSC with V8 and SpiderMonkey.
+
+ [1]: https://tc39.es/ecma262/#sec-array.prototype.indexof
+ [2]: https://tc39.es/ecma262/#sec-%typedarray%.prototype.lastindexof
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncIndexOf):
+ (JSC::arrayProtoFuncLastIndexOf):
+ * runtime/JSGenericTypedArrayViewPrototypeFunctions.h:
+ (JSC::genericTypedArrayViewProtoFuncIndexOf):
+ (JSC::genericTypedArrayViewProtoFuncLastIndexOf):
+
2020-07-04 Darin Adler <[email protected]>
[Cocoa] Remove unconditional features from FeatureDefines.xcconfig, making sure they are covered in PlatformEnableCocoa.h
Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (263943 => 263944)
--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2020-07-04 20:06:27 UTC (rev 263943)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2020-07-04 20:06:54 UTC (rev 263944)
@@ -1386,6 +1386,8 @@
return { };
uint64_t length = static_cast<uint64_t>(toLength(globalObject, thisObject));
RETURN_IF_EXCEPTION(scope, { });
+ if (!length)
+ return JSValue::encode(jsNumber(-1));
uint64_t index = argumentClampedIndexFromStartOrEnd(globalObject, callFrame->argument(1), length);
RETURN_IF_EXCEPTION(scope, { });
@@ -1423,7 +1425,8 @@
if (UNLIKELY(!thisObject))
return { };
uint64_t length = static_cast<uint64_t>(toLength(globalObject, thisObject));
- if (UNLIKELY(scope.exception()) || !length)
+ RETURN_IF_EXCEPTION(scope, { });
+ if (!length)
return JSValue::encode(jsNumber(-1));
uint64_t index = length - 1;
Modified: trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewPrototypeFunctions.h (263943 => 263944)
--- trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewPrototypeFunctions.h 2020-07-04 20:06:27 UTC (rev 263943)
+++ trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewPrototypeFunctions.h 2020-07-04 20:06:54 UTC (rev 263944)
@@ -233,11 +233,11 @@
if (thisObject->isNeutered())
return throwVMTypeError(globalObject, scope, typedArrayBufferHasBeenDetachedErrorMessage);
- if (!callFrame->argumentCount())
- return throwVMTypeError(globalObject, scope, "Expected at least one argument"_s);
-
unsigned length = thisObject->length();
+ if (!length)
+ return JSValue::encode(jsNumber(-1));
+
JSValue valueToFind = callFrame->argument(0);
unsigned index = argumentClampedIndexFromStartOrEnd(globalObject, callFrame->argument(1), length);
RETURN_IF_EXCEPTION(scope, encodedJSValue());
@@ -309,11 +309,11 @@
if (thisObject->isNeutered())
return throwVMTypeError(globalObject, scope, typedArrayBufferHasBeenDetachedErrorMessage);
- if (!callFrame->argumentCount())
- return throwVMTypeError(globalObject, scope, "Expected at least one argument"_s);
-
unsigned length = thisObject->length();
+ if (!length)
+ return JSValue::encode(jsNumber(-1));
+
JSValue valueToFind = callFrame->argument(0);
int index = length - 1;