diff --git a/src/js/typedarray.js b/src/js/typedarray.js index 0bfa8abf20..0a376d55b2 100644 --- a/src/js/typedarray.js +++ b/src/js/typedarray.js @@ -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); diff --git a/test/test262/test262.status b/test/test262/test262.status index e1befabe17..736a56f441 100644 --- a/test/test262/test262.status +++ b/test/test262/test262.status @@ -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.