Commit 86d0dd36 authored by caitp's avatar caitp Committed by Commit bot

[builtins] implement Array.prototype[@@iterator] in TFJ builtins

Implements the variations of CreateArrayIterator() in TFJ builtins
(ArrayPrototypeValues, ArrayPrototypeEntries and ArrayPrototypeKeys), and
provides two new Object types with numerous maps which identify certain
behaviours, which will be useful for inlining.

Removes src/js/array-iterator.js entirely

Also adds support for printing Symbol literals inserted by the Parser during
desugaring when FLAG_print_builtin_ast is set to true.

BUG=v8:5388
R=bmeurer@chromium.org, cbruni@chromium.org
TBR=ulan@chromium.org

Review-Url: https://codereview.chromium.org/2405253006
Cr-Commit-Position: refs/heads/master@{#40373}
parent f2a5c65b
......@@ -418,7 +418,6 @@ action("js2c") {
"src/js/collection-iterator.js",
"src/js/promise.js",
"src/js/messages.js",
"src/js/array-iterator.js",
"src/js/templates.js",
"src/js/spread.js",
"src/js/proxy.js",
......
......@@ -220,6 +220,43 @@ AstType::bitset AstBitsetType::Lub(i::Map* map) {
case JS_SET_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
case JS_STRING_ITERATOR_TYPE:
case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
case JS_WEAK_MAP_TYPE:
case JS_WEAK_SET_TYPE:
case JS_PROMISE_TYPE:
......
......@@ -529,6 +529,18 @@ void AstPrinter::PrintLiteral(Handle<Object> value, bool quote) {
}
} else if (object->IsFixedArray()) {
Print("FixedArray");
} else if (object->IsSymbol()) {
// Symbols can only occur as literals if they were inserted by the parser.
Symbol* symbol = Symbol::cast(object);
if (symbol->name()->IsString()) {
int length = 0;
String* string = String::cast(symbol->name());
std::unique_ptr<char[]> desc = string->ToCString(
ALLOW_NULLS, FAST_STRING_TRAVERSAL, 0, string->length(), &length);
Print("Symbol(%*s)", length, desc.get());
} else {
Print("Symbol()");
}
} else {
Print("<unknown literal %p>", static_cast<void*>(object));
}
......
......@@ -1310,6 +1310,91 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
native_context()->set_is_arraylike(*is_arraylike);
}
{ // --- A r r a y I t e r a t o r ---
Handle<JSObject> iterator_prototype(
native_context()->initial_iterator_prototype());
Handle<JSObject> array_iterator_prototype =
factory->NewJSObject(isolate->object_function(), TENURED);
JSObject::ForceSetPrototype(array_iterator_prototype, iterator_prototype);
JSObject::AddProperty(
array_iterator_prototype, factory->to_string_tag_symbol(),
factory->ArrayIterator_string(),
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
Handle<JSFunction> next = InstallFunction(
array_iterator_prototype, "next", JS_OBJECT_TYPE, JSObject::kHeaderSize,
MaybeHandle<JSObject>(), Builtins::kArrayIteratorPrototypeNext);
// Set the expected parameters for %ArrayIteratorPrototype%.next to 0 (not
// including the receiver), as required by the builtin.
next->shared()->set_internal_formal_parameter_count(0);
// Set the length for the function to satisfy ECMA-262.
next->shared()->set_length(0);
Handle<JSFunction> array_iterator_function = CreateFunction(
isolate, factory->ArrayIterator_string(),
JS_FAST_ARRAY_VALUE_ITERATOR_TYPE, JSArrayIterator::kSize,
array_iterator_prototype, Builtins::kIllegal);
array_iterator_function->shared()->set_instance_class_name(
isolate->heap()->ArrayIterator_string());
Handle<Map> initial_map(array_iterator_function->initial_map(), isolate);
#define ARRAY_ITERATOR_LIST(V) \
V(TYPED_ARRAY, KEY, typed_array, key) \
V(FAST_ARRAY, KEY, fast_array, key) \
V(GENERIC_ARRAY, KEY, array, key) \
V(UINT8_ARRAY, KEY_VALUE, uint8_array, key_value) \
V(INT8_ARRAY, KEY_VALUE, int8_array, key_value) \
V(UINT16_ARRAY, KEY_VALUE, uint16_array, key_value) \
V(INT16_ARRAY, KEY_VALUE, int16_array, key_value) \
V(UINT32_ARRAY, KEY_VALUE, uint32_array, key_value) \
V(INT32_ARRAY, KEY_VALUE, int32_array, key_value) \
V(FLOAT32_ARRAY, KEY_VALUE, float32_array, key_value) \
V(FLOAT64_ARRAY, KEY_VALUE, float64_array, key_value) \
V(UINT8_CLAMPED_ARRAY, KEY_VALUE, uint8_clamped_array, key_value) \
V(FAST_SMI_ARRAY, KEY_VALUE, fast_smi_array, key_value) \
V(FAST_HOLEY_SMI_ARRAY, KEY_VALUE, fast_holey_smi_array, key_value) \
V(FAST_ARRAY, KEY_VALUE, fast_array, key_value) \
V(FAST_HOLEY_ARRAY, KEY_VALUE, fast_holey_array, key_value) \
V(FAST_DOUBLE_ARRAY, KEY_VALUE, fast_double_array, key_value) \
V(FAST_HOLEY_DOUBLE_ARRAY, KEY_VALUE, fast_holey_double_array, key_value) \
V(GENERIC_ARRAY, KEY_VALUE, array, key_value) \
V(UINT8_ARRAY, VALUE, uint8_array, value) \
V(INT8_ARRAY, VALUE, int8_array, value) \
V(UINT16_ARRAY, VALUE, uint16_array, value) \
V(INT16_ARRAY, VALUE, int16_array, value) \
V(UINT32_ARRAY, VALUE, uint32_array, value) \
V(INT32_ARRAY, VALUE, int32_array, value) \
V(FLOAT32_ARRAY, VALUE, float32_array, value) \
V(FLOAT64_ARRAY, VALUE, float64_array, value) \
V(UINT8_CLAMPED_ARRAY, VALUE, uint8_clamped_array, value) \
V(FAST_SMI_ARRAY, VALUE, fast_smi_array, value) \
V(FAST_HOLEY_SMI_ARRAY, VALUE, fast_holey_smi_array, value) \
V(FAST_ARRAY, VALUE, fast_array, value) \
V(FAST_HOLEY_ARRAY, VALUE, fast_holey_array, value) \
V(FAST_DOUBLE_ARRAY, VALUE, fast_double_array, value) \
V(FAST_HOLEY_DOUBLE_ARRAY, VALUE, fast_holey_double_array, value) \
V(GENERIC_ARRAY, VALUE, array, value)
#define CREATE_ARRAY_ITERATOR_MAP(PREFIX, SUFFIX, prefix, suffix) \
do { \
const InstanceType type = JS_##PREFIX##_##SUFFIX##_ITERATOR_TYPE; \
Handle<Map> map = \
Map::Copy(initial_map, "JS_" #PREFIX "_" #SUFFIX "_ITERATOR_TYPE"); \
map->set_instance_type(type); \
native_context()->set_##prefix##_##suffix##_iterator_map(*map); \
} while (0);
ARRAY_ITERATOR_LIST(CREATE_ARRAY_ITERATOR_MAP)
#undef CREATE_ARRAY_ITERATOR_MAP
#undef ARRAY_ITERATOR_LIST
}
{ // --- N u m b e r ---
Handle<JSFunction> number_fun = InstallFunction(
global, "Number", JS_VALUE_TYPE, JSValue::kSize,
......@@ -2092,6 +2177,17 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
SimpleInstallGetter(prototype, factory->length_string(),
Builtins::kTypedArrayPrototypeLength, true,
kTypedArrayLength);
// Install "keys", "values" and "entries" methods on the {prototype}.
SimpleInstallFunction(prototype, factory->entries_string(),
Builtins::kTypedArrayPrototypeEntries, 0, true);
SimpleInstallFunction(prototype, factory->keys_string(),
Builtins::kTypedArrayPrototypeKeys, 0, true);
Handle<JSFunction> iterator =
SimpleInstallFunction(prototype, factory->values_string(),
Builtins::kTypedArrayPrototypeValues, 0, true);
JSObject::AddProperty(prototype, factory->iterator_symbol(), iterator,
DONT_ENUM);
}
{ // -- T y p e d A r r a y s
......
This diff is collapsed.
......@@ -42,15 +42,8 @@ void Generate_TypedArrayProtoypeGetter(CodeStubAssembler* assembler,
// Check if the {receiver}'s JSArrayBuffer was neutered.
Node* receiver_buffer =
assembler->LoadObjectField(receiver, JSTypedArray::kBufferOffset);
Node* receiver_buffer_bit_field = assembler->LoadObjectField(
receiver_buffer, JSArrayBuffer::kBitFieldOffset, MachineType::Uint32());
Label if_receiverisneutered(assembler, Label::kDeferred);
assembler->GotoUnless(
assembler->Word32Equal(
assembler->Word32And(
receiver_buffer_bit_field,
assembler->Int32Constant(JSArrayBuffer::WasNeutered::kMask)),
assembler->Int32Constant(0)),
assembler->GotoIf(assembler->IsDetachedBuffer(receiver_buffer),
&if_receiverisneutered);
assembler->Return(assembler->LoadObjectField(receiver, object_offset));
......@@ -98,5 +91,79 @@ void Builtins::Generate_TypedArrayPrototypeLength(
JSTypedArray::kLengthOffset);
}
namespace {
template <IterationKind kIterationKind>
void Generate_TypedArrayPrototypeIterationMethod(CodeStubAssembler* assembler,
const char* method_name) {
typedef compiler::Node Node;
typedef CodeStubAssembler::Label Label;
typedef CodeStubAssembler::Variable Variable;
Node* receiver = assembler->Parameter(0);
Node* context = assembler->Parameter(3);
Label throw_bad_receiver(assembler, Label::kDeferred);
Label throw_typeerror(assembler, Label::kDeferred);
assembler->GotoIf(assembler->TaggedIsSmi(receiver), &throw_bad_receiver);
Node* map = assembler->LoadMap(receiver);
Node* instance_type = assembler->LoadMapInstanceType(map);
assembler->GotoIf(
assembler->Word32NotEqual(instance_type,
assembler->Int32Constant(JS_TYPED_ARRAY_TYPE)),
&throw_bad_receiver);
// Check if the {receiver}'s JSArrayBuffer was neutered.
Node* receiver_buffer =
assembler->LoadObjectField(receiver, JSTypedArray::kBufferOffset);
Label if_receiverisneutered(assembler, Label::kDeferred);
assembler->GotoIf(assembler->IsDetachedBuffer(receiver_buffer),
&if_receiverisneutered);
assembler->Return(assembler->CreateArrayIterator(receiver, map, instance_type,
context, kIterationKind));
Variable var_message(assembler, MachineRepresentation::kTagged);
assembler->Bind(&throw_bad_receiver);
var_message.Bind(
assembler->SmiConstant(Smi::FromInt(MessageTemplate::kNotTypedArray)));
assembler->Goto(&throw_typeerror);
assembler->Bind(&if_receiverisneutered);
var_message.Bind(assembler->SmiConstant(
Smi::FromInt(MessageTemplate::kDetachedOperation)));
assembler->Goto(&throw_typeerror);
assembler->Bind(&throw_typeerror);
{
Node* arg1 = assembler->HeapConstant(
assembler->isolate()->factory()->NewStringFromAsciiChecked(method_name,
TENURED));
Node* result = assembler->CallRuntime(Runtime::kThrowTypeError, context,
var_message.value(), arg1);
assembler->Return(result);
}
}
} // namespace
void Builtins::Generate_TypedArrayPrototypeValues(
CodeStubAssembler* assembler) {
Generate_TypedArrayPrototypeIterationMethod<IterationKind::kValues>(
assembler, "%TypedArray%.prototype.values()");
}
void Builtins::Generate_TypedArrayPrototypeEntries(
CodeStubAssembler* assembler) {
Generate_TypedArrayPrototypeIterationMethod<IterationKind::kEntries>(
assembler, "%TypedArray%.prototype.entries()");
}
void Builtins::Generate_TypedArrayPrototypeKeys(CodeStubAssembler* assembler) {
Generate_TypedArrayPrototypeIterationMethod<IterationKind::kKeys>(
assembler, "%TypedArray%.prototype.keys()");
}
} // namespace internal
} // namespace v8
......@@ -223,6 +223,14 @@ namespace internal {
CPP(ArraySlice) \
CPP(ArraySplice) \
CPP(ArrayUnshift) \
/* ES6 #sec-array.prototype.entries */ \
TFJ(ArrayPrototypeEntries, 1) \
/* ES6 #sec-array.prototype.keys */ \
TFJ(ArrayPrototypeKeys, 1) \
/* ES6 #sec-array.prototype.values */ \
TFJ(ArrayPrototypeValues, 1) \
/* ES6 #sec-%arrayiteratorprototype%.next */ \
TFJ(ArrayIteratorPrototypeNext, 1) \
\
/* ArrayBuffer */ \
CPP(ArrayBufferConstructor) \
......@@ -670,6 +678,12 @@ namespace internal {
TFJ(TypedArrayPrototypeByteOffset, 1) \
/* ES6 section 22.2.3.18 get %TypedArray%.prototype.length */ \
TFJ(TypedArrayPrototypeLength, 1) \
/* ES6 #sec-%typedarray%.prototype.entries */ \
TFJ(TypedArrayPrototypeEntries, 1) \
/* ES6 #sec-%typedarray%.prototype.keys */ \
TFJ(TypedArrayPrototypeKeys, 1) \
/* ES6 #sec-%typedarray%.prototype.values */ \
TFJ(TypedArrayPrototypeValues, 1) \
\
CPP(ModuleNamespaceIterator) \
CPP(FixedArrayIteratorNext)
......
This diff is collapsed.
......@@ -20,6 +20,8 @@ class StubCache;
enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
enum class IterationKind { kKeys, kValues, kEntries };
#define HEAP_CONSTANT_LIST(V) \
V(BooleanMap, BooleanMap) \
V(empty_string, EmptyString) \
......@@ -140,6 +142,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
WordOr(BitcastTaggedToWord(a), BitcastTaggedToWord(b)));
}
// Smi | HeapNumber operations.
compiler::Node* NumberInc(compiler::Node* value);
// Allocate an object of the given size.
compiler::Node* Allocate(compiler::Node* size, AllocationFlags flags = kNone);
compiler::Node* Allocate(int size, AllocationFlags flags = kNone);
......@@ -296,6 +301,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* LoadDoubleWithHoleCheck(
compiler::Node* base, compiler::Node* offset, Label* if_hole,
MachineType machine_type = MachineType::Float64());
compiler::Node* LoadFixedTypedArrayElement(
compiler::Node* data_pointer, compiler::Node* index_node,
ElementsKind elements_kind,
ParameterMode parameter_mode = INTEGER_PARAMETERS);
// Context manipulation
compiler::Node* LoadContextElement(compiler::Node* context, int slot_index);
......@@ -407,6 +416,17 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
ParameterMode mode = INTEGER_PARAMETERS,
AllocationFlags flags = kNone);
// Perform CreateArrayIterator (ES6 #sec-createarrayiterator).
compiler::Node* CreateArrayIterator(compiler::Node* array,
compiler::Node* array_map,
compiler::Node* array_type,
compiler::Node* context,
IterationKind mode);
compiler::Node* AllocateJSArrayIterator(compiler::Node* array,
compiler::Node* array_map,
compiler::Node* map);
void FillFixedArrayWithValue(ElementsKind kind, compiler::Node* array,
compiler::Node* from_index,
compiler::Node* to_index,
......@@ -908,6 +928,14 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* lhs, compiler::Node* rhs,
compiler::Node* context);
void BranchIfNumericRelationalComparison(RelationalComparisonMode mode,
compiler::Node* lhs,
compiler::Node* rhs, Label* if_true,
Label* if_false);
void GotoUnlessNumberLessThan(compiler::Node* lhs, compiler::Node* rhs,
Label* if_false);
enum ResultMode { kDontNegateResult, kNegateResult };
compiler::Node* Equal(ResultMode mode, compiler::Node* lhs,
......@@ -927,6 +955,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
compiler::Node* InstanceOf(compiler::Node* object, compiler::Node* callable,
compiler::Node* context);
// TypedArray/ArrayBuffer helpers
compiler::Node* IsDetachedBuffer(compiler::Node* buffer);
private:
enum ElementSupport { kOnlyProperties, kSupportElements };
......
......@@ -215,6 +215,43 @@ Type::bitset BitsetType::Lub(i::Map* map) {
case JS_SET_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
case JS_STRING_ITERATOR_TYPE:
case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
case JS_WEAK_MAP_TYPE:
case JS_WEAK_SET_TYPE:
case JS_PROMISE_TYPE:
......
......@@ -112,6 +112,73 @@ enum ContextLookupFlags {
wasm_compile_error_function) \
V(WASM_RUNTIME_ERROR_FUNCTION_INDEX, JSFunction, wasm_runtime_error_function)
#define NATIVE_CONTEXT_JS_ARRAY_ITERATOR_MAPS(V) \
V(TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX, Map, typed_array_key_iterator_map) \
V(FAST_ARRAY_KEY_ITERATOR_MAP_INDEX, Map, fast_array_key_iterator_map) \
V(GENERIC_ARRAY_KEY_ITERATOR_MAP_INDEX, Map, array_key_iterator_map) \
\
V(UINT8_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
uint8_array_key_value_iterator_map) \
V(INT8_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
int8_array_key_value_iterator_map) \
V(UINT16_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
uint16_array_key_value_iterator_map) \
V(INT16_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
int16_array_key_value_iterator_map) \
V(UINT32_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
uint32_array_key_value_iterator_map) \
V(INT32_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
int32_array_key_value_iterator_map) \
V(FLOAT32_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
float32_array_key_value_iterator_map) \
V(FLOAT64_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
float64_array_key_value_iterator_map) \
V(UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
uint8_clamped_array_key_value_iterator_map) \
\
V(FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
fast_smi_array_key_value_iterator_map) \
V(FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
fast_holey_smi_array_key_value_iterator_map) \
V(FAST_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
fast_array_key_value_iterator_map) \
V(FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
fast_holey_array_key_value_iterator_map) \
V(FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
fast_double_array_key_value_iterator_map) \
V(FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
fast_holey_double_array_key_value_iterator_map) \
V(GENERIC_ARRAY_KEY_VALUE_ITERATOR_MAP_INDEX, Map, \
array_key_value_iterator_map) \
\
V(UINT8_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, uint8_array_value_iterator_map) \
V(INT8_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, int8_array_value_iterator_map) \
V(UINT16_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
uint16_array_value_iterator_map) \
V(INT16_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, int16_array_value_iterator_map) \
V(UINT32_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
uint32_array_value_iterator_map) \
V(INT32_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, int32_array_value_iterator_map) \
V(FLOAT32_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
float32_array_value_iterator_map) \
V(FLOAT64_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
float64_array_value_iterator_map) \
V(UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
uint8_clamped_array_value_iterator_map) \
\
V(FAST_SMI_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
fast_smi_array_value_iterator_map) \
V(FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
fast_holey_smi_array_value_iterator_map) \
V(FAST_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, fast_array_value_iterator_map) \
V(FAST_HOLEY_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
fast_holey_array_value_iterator_map) \
V(FAST_DOUBLE_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
fast_double_array_value_iterator_map) \
V(FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, \
fast_holey_double_array_value_iterator_map) \
V(GENERIC_ARRAY_VALUE_ITERATOR_MAP_INDEX, Map, array_value_iterator_map)
#define NATIVE_CONTEXT_FIELDS(V) \
V(GLOBAL_PROXY_INDEX, JSObject, global_proxy_object) \
V(EMBEDDER_DATA_INDEX, FixedArray, embedder_data) \
......@@ -256,7 +323,8 @@ enum ContextLookupFlags {
V(UINT8X16_FUNCTION_INDEX, JSFunction, uint8x16_function) \
V(CURRENT_MODULE_INDEX, Module, current_module) \
NATIVE_CONTEXT_INTRINSIC_FUNCTIONS(V) \
NATIVE_CONTEXT_IMPORTED_FIELDS(V)
NATIVE_CONTEXT_IMPORTED_FIELDS(V) \
NATIVE_CONTEXT_JS_ARRAY_ITERATOR_MAPS(V)
// A table of all script contexts. Every loaded top-level script with top-level
// lexical declarations contributes its ScriptContext into this table.
......@@ -369,7 +437,7 @@ class Context: public FixedArray {
static inline Context* cast(Object* context);
// The default context slot layout; indices are FixedArray slot indices.
enum {
enum Field {
// These slots are in all contexts.
CLOSURE_INDEX,
PREVIOUS_INDEX,
......@@ -575,6 +643,8 @@ class Context: public FixedArray {
STATIC_ASSERT(EMBEDDER_DATA_INDEX == Internals::kContextEmbedderDataIndex);
};
typedef Context::Field ContextField;
} // namespace internal
} // namespace v8
......
......@@ -12,6 +12,7 @@
V(Arguments_string, "Arguments") \
V(arguments_to_string, "[object Arguments]") \
V(Array_string, "Array") \
V(ArrayIterator_string, "Array Iterator") \
V(assign_string, "assign") \
V(array_to_string, "[object Array]") \
V(boolean_to_string, "[object Boolean]") \
......@@ -96,6 +97,7 @@
V(isView_string, "isView") \
V(KeyedLoadMonomorphic_string, "KeyedLoadMonomorphic") \
V(KeyedStoreMonomorphic_string, "KeyedStoreMonomorphic") \
V(keys_string, "keys") \
V(lastIndex_string, "lastIndex") \
V(length_string, "length") \
V(line_string, "line") \
......
......@@ -122,6 +122,43 @@ StaticVisitorBase::VisitorId StaticVisitorBase::GetVisitorId(
case JS_SET_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
case JS_STRING_ITERATOR_TYPE:
case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
case JS_PROMISE_TYPE:
case JS_BOUND_FUNCTION_TYPE:
return GetVisitorIdForSize(kVisitJSObject, kVisitJSObjectGeneric,
......
// 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 toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
var GlobalTypedArray = %object_get_prototype_of(global.Uint8Array);
// -----------------------------------------------------------------------
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 %make_type_error(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 %make_type_error(kNotTypedArray);
return %_Call(ArrayEntries, this);
}
function TypedArrayValues() {
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
return %_Call(ArrayValues, this);
}
function TypedArrayKeys() {
if (!IS_TYPEDARRAY(this)) throw %make_type_error(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 these calls once 'values' is in the above
// InstallFunctions block, as they'll be redundant.
utils.SetFunctionName(ArrayValues, 'values');
%FunctionRemovePrototype(ArrayValues);
%SetNativeFlag(ArrayValues);
%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]);
})
......@@ -1539,6 +1539,8 @@ var getFunction = function(name, jsBuiltin, len) {
return f;
};
var ArrayValues = getFunction("values", null, 0);
// Set up non-enumerable functions of the Array.prototype object and
// set their names.
// Manipulate the length of some of the functions to meet
......@@ -1568,9 +1570,14 @@ utils.InstallFunctions(GlobalArray.prototype, DONT_ENUM, [
"find", getFunction("find", ArrayFind, 1),
"findIndex", getFunction("findIndex", ArrayFindIndex, 1),
"fill", getFunction("fill", ArrayFill, 1),
"includes", getFunction("includes", null, 1)
"includes", getFunction("includes", null, 1),
"keys", getFunction("keys", null, 0),
"entries", getFunction("entries", null, 0),
iteratorSymbol, ArrayValues
]);
%FunctionSetName(ArrayValues, "values");
utils.InstallGetter(GlobalArray, speciesSymbol, ArraySpecies);
%FinishArrayPrototypeSetup(GlobalArray.prototype);
......@@ -1614,6 +1621,7 @@ utils.Export(function(to) {
to.ArrayJoin = ArrayJoin;
to.ArrayPush = ArrayPush;
to.ArrayToString = ArrayToString;
to.ArrayValues = ArrayValues;
to.InnerArrayCopyWithin = InnerArrayCopyWithin;
to.InnerArrayEvery = InnerArrayEvery;
to.InnerArrayFill = InnerArrayFill;
......@@ -1638,6 +1646,7 @@ utils.Export(function(to) {
"array_splice", ArraySplice,
"array_slice", ArraySlice,
"array_unshift", ArrayUnshift,
"array_values_iterator", ArrayValues,
]);
});
......@@ -477,6 +477,43 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3) {
case JS_SET_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
case JS_STRING_ITERATOR_TYPE:
case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
case JS_REGEXP_TYPE:
case JS_GLOBAL_PROXY_TYPE:
case JS_GLOBAL_OBJECT_TYPE:
......
......@@ -158,6 +158,44 @@ void HeapObject::HeapObjectVerify() {
case JS_MAP_ITERATOR_TYPE:
JSMapIterator::cast(this)->JSMapIteratorVerify();
break;
case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
case JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE:
case JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT8_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT16_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_INT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE:
case JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE:
JSArrayIterator::cast(this)->JSArrayIteratorVerify();
break;
case JS_STRING_ITERATOR_TYPE:
JSStringIterator::cast(this)->JSStringIteratorVerify();
break;
......@@ -788,6 +826,16 @@ void JSWeakMap::JSWeakMapVerify() {
CHECK(table()->IsHashTable() || table()->IsUndefined(GetIsolate()));
}
void JSArrayIterator::JSArrayIteratorVerify() {
CHECK(IsJSArrayIterator());
JSObjectVerify();
CHECK(object()->IsJSReceiver() || object()->IsUndefined(GetIsolate()));
CHECK_GE(index()->Number(), 0);
CHECK_LE(index()->Number(), kMaxSafeInteger);
CHECK(object_map()->IsMap() || object_map()->IsUndefined(GetIsolate()));
}
void JSStringIterator::JSStringIteratorVerify() {
CHECK(IsJSStringIterator());
JSObjectVerify();
......
......@@ -690,6 +690,12 @@ bool HeapObject::IsJSObject() const {
bool HeapObject::IsJSProxy() const { return map()->IsJSProxyMap(); }
bool HeapObject::IsJSArrayIterator() const {
InstanceType instance_type = map()->instance_type();
return (instance_type >= FIRST_ARRAY_ITERATOR_TYPE &&
instance_type <= LAST_ARRAY_ITERATOR_TYPE);
}
TYPE_CHECKER(JSSet, JS_SET_TYPE)
TYPE_CHECKER(JSMap, JS_MAP_TYPE)
TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE)
......@@ -3338,6 +3344,7 @@ CAST_ACCESSOR(JSRegExp)
CAST_ACCESSOR(JSSet)
CAST_ACCESSOR(JSSetIterator)
CAST_ACCESSOR(JSStringIterator)
CAST_ACCESSOR(JSArrayIterator)
CAST_ACCESSOR(JSTypedArray)
CAST_ACCESSOR(JSValue)
CAST_ACCESSOR(JSWeakCollection)
......@@ -8357,6 +8364,10 @@ static inline Handle<Object> MakeEntryPair(Isolate* isolate, Handle<Name> key,
ACCESSORS(JSIteratorResult, value, Object, kValueOffset)
ACCESSORS(JSIteratorResult, done, Object, kDoneOffset)
ACCESSORS(JSArrayIterator, object, Object, kIteratedObjectOffset)
ACCESSORS(JSArrayIterator, index, Object, kNextIndexOffset)
ACCESSORS(JSArrayIterator, object_map, Object, kIteratedObjectMapOffset)
ACCESSORS(JSStringIterator, string, String, kStringOffset)
SMI_ACCESSORS(JSStringIterator, index, kNextIndexOffset)
......
......@@ -444,6 +444,46 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
V(JS_ERROR_TYPE) \
V(JS_STRING_ITERATOR_TYPE) \
\
V(JS_TYPED_ARRAY_KEY_ITERATOR_TYPE) \
V(JS_FAST_ARRAY_KEY_ITERATOR_TYPE) \
V(JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE) \
\
V(JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
\
V(JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
V(JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE) \
\
V(JS_INT8_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_INT16_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_INT32_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE) \
\
V(JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_FAST_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE) \
V(JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE) \
\
V(JS_BOUND_FUNCTION_TYPE) \
V(JS_FUNCTION_TYPE) \
V(DEBUG_INFO_TYPE) \
......@@ -747,6 +787,47 @@ enum InstanceType {
JS_REGEXP_TYPE,
JS_ERROR_TYPE,
JS_STRING_ITERATOR_TYPE,
JS_TYPED_ARRAY_KEY_ITERATOR_TYPE,
JS_FAST_ARRAY_KEY_ITERATOR_TYPE,
JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE,
JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE,
JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE,
JS_INT8_ARRAY_VALUE_ITERATOR_TYPE,
JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE,
JS_INT16_ARRAY_VALUE_ITERATOR_TYPE,
JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE,
JS_INT32_ARRAY_VALUE_ITERATOR_TYPE,
JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE,
JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE,
JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE,
JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE,
JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE,
JS_FAST_ARRAY_VALUE_ITERATOR_TYPE,
JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE,
JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE,
JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE,
JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE,
JS_BOUND_FUNCTION_TYPE,
JS_FUNCTION_TYPE, // LAST_JS_OBJECT_TYPE, LAST_JS_RECEIVER_TYPE
......@@ -783,6 +864,18 @@ enum InstanceType {
// an empty fixed array as elements backing store. This is true for string
// wrappers.
LAST_CUSTOM_ELEMENTS_RECEIVER = JS_VALUE_TYPE,
FIRST_ARRAY_KEY_ITERATOR_TYPE = JS_TYPED_ARRAY_KEY_ITERATOR_TYPE,
LAST_ARRAY_KEY_ITERATOR_TYPE = JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE,
FIRST_ARRAY_KEY_VALUE_ITERATOR_TYPE = JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE,
LAST_ARRAY_KEY_VALUE_ITERATOR_TYPE = JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE,
FIRST_ARRAY_VALUE_ITERATOR_TYPE = JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE,
LAST_ARRAY_VALUE_ITERATOR_TYPE = JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE,
FIRST_ARRAY_ITERATOR_TYPE = FIRST_ARRAY_KEY_ITERATOR_TYPE,
LAST_ARRAY_ITERATOR_TYPE = LAST_ARRAY_VALUE_ITERATOR_TYPE,
};
STATIC_ASSERT(JS_OBJECT_TYPE == Internals::kJSObjectType);
......@@ -1028,6 +1121,7 @@ template <class C> inline bool Is(Object* obj);
V(JSArrayBufferView) \
V(JSCollection) \
V(JSTypedArray) \
V(JSArrayIterator) \
V(JSDataView) \
V(JSProxy) \
V(JSError) \
......@@ -10515,6 +10609,32 @@ class JSMap : public JSCollection {
DISALLOW_IMPLICIT_CONSTRUCTORS(JSMap);
};
class JSArrayIterator : public JSObject {
public:
DECLARE_PRINTER(JSArrayIterator)
DECLARE_VERIFIER(JSArrayIterator)
DECLARE_CAST(JSArrayIterator)
// [object]: the [[IteratedObject]] internal field.
DECL_ACCESSORS(object, Object)
// [index]: The [[ArrayIteratorNextIndex]] internal field.
DECL_ACCESSORS(index, Object)
// [map]: The Map of the [[IteratedObject]] field at the time the iterator is
// allocated.
DECL_ACCESSORS(object_map, Object)
static const int kIteratedObjectOffset = JSObject::kHeaderSize;
static const int kNextIndexOffset = kIteratedObjectOffset + kPointerSize;
static const int kIteratedObjectMapOffset = kNextIndexOffset + kPointerSize;
static const int kSize = kIteratedObjectMapOffset + kPointerSize;
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSArrayIterator);
};
class JSStringIterator : public JSObject {
public:
// Dispatched behavior.
......
......@@ -71,6 +71,10 @@ RUNTIME_FUNCTION(Runtime_SpecialArrayFunctions) {
InstallBuiltin(isolate, holder, "splice", Builtins::kArraySplice);
InstallBuiltin(isolate, holder, "includes", Builtins::kArrayIncludes, 2);
InstallBuiltin(isolate, holder, "indexOf", Builtins::kArrayIndexOf, 2);
InstallBuiltin(isolate, holder, "keys", Builtins::kArrayPrototypeKeys, 0);
InstallBuiltin(isolate, holder, "values", Builtins::kArrayPrototypeValues, 0);
InstallBuiltin(isolate, holder, "entries", Builtins::kArrayPrototypeEntries,
0);
return *holder;
}
......
......@@ -2238,7 +2238,6 @@
'js/collection-iterator.js',
'js/promise.js',
'js/messages.js',
'js/array-iterator.js',
'js/templates.js',
'js/spread.js',
'js/proxy.js',
......
......@@ -193,7 +193,6 @@
# https://bugs.chromium.org/p/v8/issues/detail?id=4648
'built-ins/TypedArray/prototype/copyWithin/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/entries/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/every/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/fill/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/filter/detached-buffer': [FAIL],
......@@ -203,7 +202,6 @@
'built-ins/TypedArray/prototype/includes/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/indexOf/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/join/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/keys/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/lastIndexOf/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/map/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/reverse/detached-buffer': [FAIL],
......@@ -213,7 +211,6 @@
'built-ins/TypedArray/prototype/subarray/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/toLocaleString/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/toString/detached-buffer': [FAIL],
'built-ins/TypedArray/prototype/values/detached-buffer': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=4034
'built-ins/ThrowTypeError/unique-per-realm-function-proto': [FAIL],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment