04aa9436ce
Instead of directly looking up Uint8Array.__proto__, to get a hold of the TypedArray prototype, use object_get_prototype_of. This is a functionally equivalent, but cleaner approach. Review-Url: https://codereview.chromium.org/1990983002 Cr-Commit-Position: refs/heads/master@{#36340}
172 lines
4.8 KiB
JavaScript
172 lines
4.8 KiB
JavaScript
// Copyright 2013 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
(function(global, utils) {
|
|
|
|
"use strict";
|
|
|
|
%CheckIsBootstrapping();
|
|
|
|
// -----------------------------------------------------------------------
|
|
// Imports
|
|
|
|
var arrayIterationKindSymbol =
|
|
utils.ImportNow("array_iteration_kind_symbol");
|
|
var arrayIteratorNextIndexSymbol =
|
|
utils.ImportNow("array_iterator_next_symbol");
|
|
var arrayIteratorObjectSymbol =
|
|
utils.ImportNow("array_iterator_object_symbol");
|
|
var GlobalArray = global.Array;
|
|
var IteratorPrototype = utils.ImportNow("IteratorPrototype");
|
|
var iteratorSymbol = utils.ImportNow("iterator_symbol");
|
|
var MakeTypeError;
|
|
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
|
|
var GlobalTypedArray = %object_get_prototype_of(global.Uint8Array);
|
|
|
|
utils.Import(function(from) {
|
|
MakeTypeError = from.MakeTypeError;
|
|
})
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
function ArrayIterator() {}
|
|
|
|
|
|
// TODO(wingo): Update section numbers when ES6 has stabilized. The
|
|
// section numbers below are already out of date as of the May 2014
|
|
// draft.
|
|
|
|
|
|
// 15.4.5.1 CreateArrayIterator Abstract Operation
|
|
function CreateArrayIterator(array, kind) {
|
|
var object = TO_OBJECT(array);
|
|
var iterator = new ArrayIterator;
|
|
SET_PRIVATE(iterator, arrayIteratorObjectSymbol, object);
|
|
SET_PRIVATE(iterator, arrayIteratorNextIndexSymbol, 0);
|
|
SET_PRIVATE(iterator, arrayIterationKindSymbol, kind);
|
|
return iterator;
|
|
}
|
|
|
|
|
|
// 22.1.5.2.2 %ArrayIteratorPrototype%[@@iterator]
|
|
function ArrayIteratorIterator() {
|
|
return this;
|
|
}
|
|
|
|
|
|
// ES6 section 22.1.5.2.1 %ArrayIteratorPrototype%.next( )
|
|
function ArrayIteratorNext() {
|
|
var iterator = this;
|
|
var value = UNDEFINED;
|
|
var done = true;
|
|
|
|
if (!IS_RECEIVER(iterator) ||
|
|
!HAS_DEFINED_PRIVATE(iterator, arrayIteratorNextIndexSymbol)) {
|
|
throw MakeTypeError(kIncompatibleMethodReceiver,
|
|
'Array Iterator.prototype.next', this);
|
|
}
|
|
|
|
var array = GET_PRIVATE(iterator, arrayIteratorObjectSymbol);
|
|
if (!IS_UNDEFINED(array)) {
|
|
var index = GET_PRIVATE(iterator, arrayIteratorNextIndexSymbol);
|
|
var itemKind = GET_PRIVATE(iterator, arrayIterationKindSymbol);
|
|
var length = TO_UINT32(array.length);
|
|
|
|
// "sparse" is never used.
|
|
|
|
if (index >= length) {
|
|
SET_PRIVATE(iterator, arrayIteratorObjectSymbol, UNDEFINED);
|
|
} else {
|
|
SET_PRIVATE(iterator, arrayIteratorNextIndexSymbol, index + 1);
|
|
|
|
if (itemKind == ITERATOR_KIND_VALUES) {
|
|
value = array[index];
|
|
} else if (itemKind == ITERATOR_KIND_ENTRIES) {
|
|
value = [index, array[index]];
|
|
} else {
|
|
value = index;
|
|
}
|
|
done = false;
|
|
}
|
|
}
|
|
|
|
return %_CreateIterResultObject(value, done);
|
|
}
|
|
|
|
|
|
function ArrayEntries() {
|
|
return CreateArrayIterator(this, ITERATOR_KIND_ENTRIES);
|
|
}
|
|
|
|
|
|
function ArrayValues() {
|
|
return CreateArrayIterator(this, ITERATOR_KIND_VALUES);
|
|
}
|
|
|
|
|
|
function ArrayKeys() {
|
|
return CreateArrayIterator(this, ITERATOR_KIND_KEYS);
|
|
}
|
|
|
|
// TODO(littledan): Check for detached TypedArray in these three methods
|
|
function TypedArrayEntries() {
|
|
if (!IS_TYPEDARRAY(this)) throw MakeTypeError(kNotTypedArray);
|
|
return %_Call(ArrayEntries, this);
|
|
}
|
|
|
|
|
|
function TypedArrayValues() {
|
|
if (!IS_TYPEDARRAY(this)) throw MakeTypeError(kNotTypedArray);
|
|
return %_Call(ArrayValues, this);
|
|
}
|
|
|
|
|
|
function TypedArrayKeys() {
|
|
if (!IS_TYPEDARRAY(this)) throw MakeTypeError(kNotTypedArray);
|
|
return %_Call(ArrayKeys, this);
|
|
}
|
|
|
|
|
|
%FunctionSetPrototype(ArrayIterator, {__proto__: IteratorPrototype});
|
|
%FunctionSetInstanceClassName(ArrayIterator, 'Array Iterator');
|
|
|
|
utils.InstallFunctions(ArrayIterator.prototype, DONT_ENUM, [
|
|
'next', ArrayIteratorNext
|
|
]);
|
|
utils.SetFunctionName(ArrayIteratorIterator, iteratorSymbol);
|
|
%AddNamedProperty(ArrayIterator.prototype, toStringTagSymbol,
|
|
"Array Iterator", READ_ONLY | DONT_ENUM);
|
|
|
|
utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
|
|
// No 'values' since it breaks webcompat: http://crbug.com/409858
|
|
'entries', ArrayEntries,
|
|
'keys', ArrayKeys
|
|
]);
|
|
|
|
// TODO(adam): Remove this call once 'values' is in the above
|
|
// InstallFunctions block, as it'll be redundant.
|
|
utils.SetFunctionName(ArrayValues, 'values');
|
|
|
|
%AddNamedProperty(GlobalArray.prototype, iteratorSymbol, ArrayValues,
|
|
DONT_ENUM);
|
|
|
|
utils.InstallFunctions(GlobalTypedArray.prototype, DONT_ENUM, [
|
|
'entries', TypedArrayEntries,
|
|
'keys', TypedArrayKeys,
|
|
'values', TypedArrayValues
|
|
]);
|
|
%AddNamedProperty(GlobalTypedArray.prototype,
|
|
iteratorSymbol, TypedArrayValues, DONT_ENUM);
|
|
|
|
// -------------------------------------------------------------------
|
|
// Exports
|
|
|
|
utils.Export(function(to) {
|
|
to.ArrayValues = ArrayValues;
|
|
});
|
|
|
|
%InstallToContext(["array_values_iterator", ArrayValues]);
|
|
|
|
})
|