v8/src/array-iterator.js
bmeurer 72bc4b5c8a [es6] Introduce a dedicated JSIteratorResult type.
Use a single JSIteratorResult type for all implementation provided
iterator results (i.e. the String, Array and collection iterators,
and also for generators).  This removes one source of unnecessary
polymorphism in for-of loops.  It is accomplished by a new intrinsic
%_CreateIterResultObject() that should be used to create iterator
result objects from JavaScript builtins (there's a matching factory
method for C++ code).

Also restructure the %StringIteratorPrototype%.next() and
%ArrayIteratorPrototype%.next() functions to be a bit more friendly
to optimizing compilers.

R=ishell@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#30557}
2015-09-03 12:16:25 +00:00

169 lines
4.7 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.
var $arrayValues;
(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 iteratorSymbol = utils.ImportNow("iterator_symbol");
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
macro TYPED_ARRAYS(FUNCTION)
FUNCTION(Uint8Array)
FUNCTION(Int8Array)
FUNCTION(Uint16Array)
FUNCTION(Int16Array)
FUNCTION(Uint32Array)
FUNCTION(Int32Array)
FUNCTION(Float32Array)
FUNCTION(Float64Array)
FUNCTION(Uint8ClampedArray)
endmacro
macro COPY_FROM_GLOBAL(NAME)
var GlobalNAME = global.NAME;
endmacro
TYPED_ARRAYS(COPY_FROM_GLOBAL)
// -----------------------------------------------------------------------
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_SPEC_OBJECT(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);
}
%FunctionSetPrototype(ArrayIterator, {__proto__: $iteratorPrototype});
%FunctionSetInstanceClassName(ArrayIterator, 'Array Iterator');
utils.InstallFunctions(ArrayIterator.prototype, DONT_ENUM, [
'next', ArrayIteratorNext
]);
utils.SetFunctionName(ArrayIteratorIterator, iteratorSymbol);
%AddNamedProperty(ArrayIterator.prototype, iteratorSymbol,
ArrayIteratorIterator, DONT_ENUM);
%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);
macro EXTEND_TYPED_ARRAY(NAME)
%AddNamedProperty(GlobalNAME.prototype, 'entries', ArrayEntries, DONT_ENUM);
%AddNamedProperty(GlobalNAME.prototype, 'values', ArrayValues, DONT_ENUM);
%AddNamedProperty(GlobalNAME.prototype, 'keys', ArrayKeys, DONT_ENUM);
%AddNamedProperty(GlobalNAME.prototype, iteratorSymbol, ArrayValues,
DONT_ENUM);
endmacro
TYPED_ARRAYS(EXTEND_TYPED_ARRAY)
// -------------------------------------------------------------------
// Exports
$arrayValues = ArrayValues;
%InstallToContext(["array_values_iterator", ArrayValues]);
})