Make %TypedArray%.from spec-compliant

This patch fixes %TypedArray%.from to follow the ES2016 draft spec
more precisely. Specifically, the input is first converted to an
ArrayLike, and then afterwards, the mapping function is run and the
results written into the TypedArray. This fixes a test262 test.

R=adamk
LOG=Y
BUG=v8:4782

Review URL: https://codereview.chromium.org/1743463004

Cr-Commit-Position: refs/heads/master@{#34373}
This commit is contained in:
littledan 2016-02-29 18:40:29 -08:00 committed by Commit bot
parent 4a6f15124f
commit 2765a0609a
2 changed files with 52 additions and 13 deletions

View File

@ -11,9 +11,11 @@
// -------------------------------------------------------------------
// Imports
var ArrayFrom;
var AddIndexedProperty;
var ArrayToString;
var ArrayValues;
var GetIterator;
var GetMethod;
var GlobalArray = global.Array;
var GlobalArrayBuffer = global.ArrayBuffer;
var GlobalDataView = global.DataView;
@ -67,9 +69,11 @@ endmacro
TYPED_ARRAYS(DECLARE_GLOBALS)
utils.Import(function(from) {
ArrayFrom = from.ArrayFrom;
AddIndexedProperty = from.AddIndexedProperty;
ArrayToString = from.ArrayToString;
ArrayValues = from.ArrayValues;
GetIterator = from.GetIterator;
GetMethod = from.GetMethod;
InnerArrayCopyWithin = from.InnerArrayCopyWithin;
InnerArrayEvery = from.InnerArrayEvery;
InnerArrayFill = from.InnerArrayFill;
@ -760,14 +764,50 @@ function TypedArrayOf() {
}
// ES#sec-iterabletoarraylike Runtime Semantics: IterableToArrayLike( items )
function IterableToArrayLike(items) {
var iterable = GetMethod(items, iteratorSymbol);
if (!IS_UNDEFINED(iterable)) {
var internal_array = new InternalArray();
var i = 0;
for (var value of
{ [iteratorSymbol]() { return GetIterator(items, iterable) } }) {
internal_array[i] = value;
i++;
}
var array = [];
%MoveArrayContents(internal_array, array);
return array;
}
return TO_OBJECT(items);
}
// ES#sec-%typedarray%.from
// %TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )
function TypedArrayFrom(source, mapfn, thisArg) {
// TODO(littledan): Investigate if there is a receiver which could be
// faster to accumulate on than Array, e.g., a TypedVector.
// TODO(littledan) BUG(v8:4782): Rewrite this code to ensure that things
// happen in the right order, e.g., the constructor needs to be called
// before the mapping function on array-likes.
var array = %_Call(ArrayFrom, GlobalArray, source, mapfn, thisArg);
return TypedArrayCreate(this, array);
if (!%IsConstructor(this)) throw MakeTypeError(kNotConstructor, this);
var mapping;
if (!IS_UNDEFINED(mapfn)) {
if (!IS_CALLABLE(mapfn)) throw MakeTypeError(kCalledNonCallable, this);
mapping = true;
} else {
mapping = false;
}
var arrayLike = IterableToArrayLike(source);
var length = TO_LENGTH(arrayLike.length);
var targetObject = TypedArrayCreate(this, length);
var value, mappedValue;
for (var i = 0; i < length; i++) {
value = arrayLike[i];
if (mapping) {
mappedValue = %_Call(mapfn, thisArg, value, i);
} else {
mappedValue = value;
}
targetObject[i] = mappedValue;
}
return targetObject;
}
%FunctionSetLength(TypedArrayFrom, 1);

View File

@ -278,10 +278,6 @@
'built-ins/TypedArrays/typedarray-arg-same-ctor-buffer-ctor-species-throws': [FAIL],
'built-ins/TypedArrays/typedarray-arg-same-ctor-buffer-ctor-value-not-obj-throws': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=4782
'built-ins/TypedArrays/from/set-value-abrupt-completion': [FAIL],
'built-ins/TypedArray/from/mapfn-is-not-callable': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=4727
'built-ins/TypedArrays/length-arg-is-undefined-throws': [FAIL],
'built-ins/TypedArrays/length-arg-is-symbol-throws': [FAIL],
@ -366,6 +362,9 @@
# Test bug https://github.com/tc39/test262/issues/518
'built-ins/TypedArrays/object-arg-throws-setting-typedarray-property': [FAIL],
# Test bug https://github.com/tc39/test262/issues/521
'built-ins/TypedArray/from/mapfn-is-not-callable': [FAIL],
############################ SKIPPED TESTS #############################
# These tests take a looong time to run.