Commit 1c48d52b authored by Hai Dang's avatar Hai Dang Committed by Commit Bot

[interpreter] Add bytecode for leading array spreads.

This CL improves the performance of creating [...a, b] or [...a].
If the array literal has a leading spread, this CL emits the bytecode
[CreateArrayFromIterable] to create the literal. CreateArrayFromIterable
is implemented by [IterableToListDefault] builtin to create the initial
array for the leading spread. IterableToListDefault has a fast path to
clone efficiently if the spread is an actual array.

The bytecode generated is now shorter. Bytecode generation is refactored
into to BuildCreateArrayLiteral, which allows VisitCallSuper to benefit
from this optimization also.
For now, turbofan also lowers the bytecode to the builtin.

The idiomatic use of [...a] to clone the array a now performs better
than a simple for-loop, but still does not match the performance of slice.

Bug: v8:7980

Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: Ibde659c82d3c7aa1b1777a3d2f6426ac8cc15e35
Reviewed-on: https://chromium-review.googlesource.com/1181024Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Commit-Queue: Hai Dang <dhai@google.com>
Cr-Commit-Position: refs/heads/master@{#55520}
parent 50089eff
...@@ -551,12 +551,6 @@ bool ObjectLiteral::IsFastCloningSupported() const { ...@@ -551,12 +551,6 @@ bool ObjectLiteral::IsFastCloningSupported() const {
ConstructorBuiltins::kMaximumClonedShallowObjectProperties; ConstructorBuiltins::kMaximumClonedShallowObjectProperties;
} }
bool ArrayLiteral::is_empty() const {
DCHECK(is_initialized());
return values()->is_empty() && (boilerplate_description().is_null() ||
boilerplate_description()->is_empty());
}
int ArrayLiteral::InitDepthAndFlags() { int ArrayLiteral::InitDepthAndFlags() {
if (is_initialized()) return depth(); if (is_initialized()) return depth();
......
...@@ -1477,8 +1477,6 @@ class ArrayLiteral final : public AggregateLiteral { ...@@ -1477,8 +1477,6 @@ class ArrayLiteral final : public AggregateLiteral {
int first_spread_index() const { return first_spread_index_; } int first_spread_index() const { return first_spread_index_; }
bool is_empty() const;
// Populate the depth field and flags, returns the depth. // Populate the depth field and flags, returns the depth.
int InitDepthAndFlags(); int InitDepthAndFlags();
......
...@@ -1130,6 +1130,7 @@ namespace internal { ...@@ -1130,6 +1130,7 @@ namespace internal {
\ \
/* TypedArray */ \ /* TypedArray */ \
TFS(IterableToList, kIterable, kIteratorFn) \ TFS(IterableToList, kIterable, kIteratorFn) \
TFS(IterableToListWithSymbolLookup, kIterable) \
TFS(TypedArrayInitialize, kHolder, kLength, kElementSize, kInitialize, \ TFS(TypedArrayInitialize, kHolder, kLength, kElementSize, kInitialize, \
kBufferConstructor) \ kBufferConstructor) \
TFS(TypedArrayInitializeWithBuffer, kHolder, kLength, kBuffer, kElementSize, \ TFS(TypedArrayInitializeWithBuffer, kHolder, kLength, kBuffer, kElementSize, \
......
...@@ -177,10 +177,8 @@ void IntlBuiltinsAssembler::ListFormatCommon(TNode<Context> context, ...@@ -177,10 +177,8 @@ void IntlBuiltinsAssembler::ListFormatCommon(TNode<Context> context,
BIND(&has_list); BIND(&has_list);
{ {
// 5. Let x be ? IterableToList(list). // 5. Let x be ? IterableToList(list).
IteratorBuiltinsAssembler iterator_assembler(state()); TNode<Object> x =
// TODO(adamk): Consider exposing IterableToList as a buitin and calling CallBuiltin(Builtins::kIterableToListWithSymbolLookup, context, list);
// it from here instead of inlining the operation.
TNode<JSArray> x = iterator_assembler.IterableToList(context, list);
// 6. Return ? FormatList(lf, x). // 6. Return ? FormatList(lf, x).
args.PopAndReturn(CallRuntime(format_func_id, context, list_format, x)); args.PopAndReturn(CallRuntime(format_func_id, context, list_format, x));
......
...@@ -38,8 +38,7 @@ IteratorRecord IteratorBuiltinsAssembler::GetIterator(Node* context, ...@@ -38,8 +38,7 @@ IteratorRecord IteratorBuiltinsAssembler::GetIterator(Node* context,
BIND(&if_not_callable); BIND(&if_not_callable);
{ {
Node* ret = CallRuntime(Runtime::kThrowTypeError, context, Node* ret = CallRuntime(Runtime::kThrowIteratorError, context, object);
SmiConstant(MessageTemplate::kNotIterable), object);
GotoIfException(ret, if_exception, exception); GotoIfException(ret, if_exception, exception);
Unreachable(); Unreachable();
} }
......
...@@ -1617,6 +1617,17 @@ TF_BUILTIN(IterableToList, TypedArrayBuiltinsAssembler) { ...@@ -1617,6 +1617,17 @@ TF_BUILTIN(IterableToList, TypedArrayBuiltinsAssembler) {
Return(iterator_assembler.IterableToList(context, iterable, iterator_fn)); Return(iterator_assembler.IterableToList(context, iterable, iterator_fn));
} }
TF_BUILTIN(IterableToListWithSymbolLookup, TypedArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable));
IteratorBuiltinsAssembler iterator_assembler(state());
TNode<Object> iterator_fn =
iterator_assembler.GetIteratorMethod(context, iterable);
TailCallBuiltin(Builtins::kIterableToList, context, iterable, iterator_fn);
}
// ES6 #sec-%typedarray%.from // ES6 #sec-%typedarray%.from
TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) { TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<Context> context = CAST(Parameter(Descriptor::kContext));
......
...@@ -1601,6 +1601,12 @@ void BytecodeGraphBuilder::VisitCreateEmptyArrayLiteral() { ...@@ -1601,6 +1601,12 @@ void BytecodeGraphBuilder::VisitCreateEmptyArrayLiteral() {
environment()->BindAccumulator(literal); environment()->BindAccumulator(literal);
} }
void BytecodeGraphBuilder::VisitCreateArrayFromIterable() {
Node* iterable = NewNode(javascript()->CreateArrayFromIterable(),
environment()->LookupAccumulator());
environment()->BindAccumulator(iterable, Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::VisitCreateObjectLiteral() { void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
Handle<ObjectBoilerplateDescription> constant_properties( Handle<ObjectBoilerplateDescription> constant_properties(
ObjectBoilerplateDescription::cast( ObjectBoilerplateDescription::cast(
......
...@@ -513,6 +513,13 @@ void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) { ...@@ -513,6 +513,13 @@ void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) {
ReplaceWithStubCall(node, callable, flags); ReplaceWithStubCall(node, callable, flags);
} }
void JSGenericLowering::LowerJSCreateArrayFromIterable(Node* node) {
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
Callable callable = Builtins::CallableFor(
isolate(), Builtins::kIterableToListWithSymbolLookup);
ReplaceWithStubCall(node, callable, flags);
}
void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) { void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = FrameStateFlagForCall(node); CallDescriptor::Flags flags = FrameStateFlagForCall(node);
......
...@@ -1190,6 +1190,14 @@ const Operator* JSOperatorBuilder::CreateEmptyLiteralArray( ...@@ -1190,6 +1190,14 @@ const Operator* JSOperatorBuilder::CreateEmptyLiteralArray(
parameters); // parameter parameters); // parameter
} }
const Operator* JSOperatorBuilder::CreateArrayFromIterable() {
return new (zone()) Operator( // --
IrOpcode::kJSCreateArrayFromIterable, // opcode
Operator::kNoProperties, // properties
"JSCreateArrayFromIterable", // name
1, 1, 1, 1, 1, 2); // counts
}
const Operator* JSOperatorBuilder::CreateLiteralObject( const Operator* JSOperatorBuilder::CreateLiteralObject(
Handle<ObjectBoilerplateDescription> constant_properties, Handle<ObjectBoilerplateDescription> constant_properties,
VectorSlotPair const& feedback, int literal_flags, VectorSlotPair const& feedback, int literal_flags,
......
...@@ -733,6 +733,7 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final ...@@ -733,6 +733,7 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
VectorSlotPair const& feedback, int literal_flags, VectorSlotPair const& feedback, int literal_flags,
int number_of_elements); int number_of_elements);
const Operator* CreateEmptyLiteralArray(VectorSlotPair const& feedback); const Operator* CreateEmptyLiteralArray(VectorSlotPair const& feedback);
const Operator* CreateArrayFromIterable();
const Operator* CreateEmptyLiteralObject(); const Operator* CreateEmptyLiteralObject();
const Operator* CreateLiteralObject( const Operator* CreateLiteralObject(
......
...@@ -151,6 +151,7 @@ ...@@ -151,6 +151,7 @@
V(JSCreateTypedArray) \ V(JSCreateTypedArray) \
V(JSCreateLiteralArray) \ V(JSCreateLiteralArray) \
V(JSCreateEmptyLiteralArray) \ V(JSCreateEmptyLiteralArray) \
V(JSCreateArrayFromIterable) \
V(JSCreateLiteralObject) \ V(JSCreateLiteralObject) \
V(JSCreateEmptyLiteralObject) \ V(JSCreateEmptyLiteralObject) \
V(JSCloneObject) \ V(JSCloneObject) \
......
...@@ -73,6 +73,7 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) { ...@@ -73,6 +73,7 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
case IrOpcode::kJSCreateArray: case IrOpcode::kJSCreateArray:
case IrOpcode::kJSCreateTypedArray: case IrOpcode::kJSCreateTypedArray:
case IrOpcode::kJSCreateLiteralArray: case IrOpcode::kJSCreateLiteralArray:
case IrOpcode::kJSCreateArrayFromIterable:
case IrOpcode::kJSCreateLiteralObject: case IrOpcode::kJSCreateLiteralObject:
case IrOpcode::kJSCreateLiteralRegExp: case IrOpcode::kJSCreateLiteralRegExp:
case IrOpcode::kJSCreateObject: case IrOpcode::kJSCreateObject:
......
...@@ -89,6 +89,7 @@ bool NeedsCheckHeapObject(Node* receiver) { ...@@ -89,6 +89,7 @@ bool NeedsCheckHeapObject(Node* receiver) {
case IrOpcode::kJSCreateIterResultObject: case IrOpcode::kJSCreateIterResultObject:
case IrOpcode::kJSCreateLiteralArray: case IrOpcode::kJSCreateLiteralArray:
case IrOpcode::kJSCreateEmptyLiteralArray: case IrOpcode::kJSCreateEmptyLiteralArray:
case IrOpcode::kJSCreateArrayFromIterable:
case IrOpcode::kJSCreateLiteralObject: case IrOpcode::kJSCreateLiteralObject:
case IrOpcode::kJSCreateEmptyLiteralObject: case IrOpcode::kJSCreateEmptyLiteralObject:
case IrOpcode::kJSCreateLiteralRegExp: case IrOpcode::kJSCreateLiteralRegExp:
......
...@@ -1215,6 +1215,10 @@ Type Typer::Visitor::TypeJSCreateEmptyLiteralArray(Node* node) { ...@@ -1215,6 +1215,10 @@ Type Typer::Visitor::TypeJSCreateEmptyLiteralArray(Node* node) {
return Type::Array(); return Type::Array();
} }
Type Typer::Visitor::TypeJSCreateArrayFromIterable(Node* node) {
return Type::Array();
}
Type Typer::Visitor::TypeJSCreateLiteralObject(Node* node) { Type Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
return Type::OtherObject(); return Type::OtherObject();
} }
......
...@@ -715,6 +715,10 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) { ...@@ -715,6 +715,10 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
// Type is Array. // Type is Array.
CheckTypeIs(node, Type::Array()); CheckTypeIs(node, Type::Array());
break; break;
case IrOpcode::kJSCreateArrayFromIterable:
// Type is Array.
CheckTypeIs(node, Type::Array());
break;
case IrOpcode::kJSCreateLiteralObject: case IrOpcode::kJSCreateLiteralObject:
case IrOpcode::kJSCreateEmptyLiteralObject: case IrOpcode::kJSCreateEmptyLiteralObject:
case IrOpcode::kJSCloneObject: case IrOpcode::kJSCloneObject:
......
...@@ -292,6 +292,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) { ...@@ -292,6 +292,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
V(ReThrow) \ V(ReThrow) \
V(ThrowCalledNonCallable) \ V(ThrowCalledNonCallable) \
V(ThrowInvalidStringLength) \ V(ThrowInvalidStringLength) \
V(ThrowIteratorError) \
V(ThrowIteratorResultNotAnObject) \ V(ThrowIteratorResultNotAnObject) \
V(ThrowReferenceError) \ V(ThrowReferenceError) \
V(ThrowSymbolIteratorInvalid) \ V(ThrowSymbolIteratorInvalid) \
...@@ -477,6 +478,7 @@ bool BytecodeHasNoSideEffect(interpreter::Bytecode bytecode) { ...@@ -477,6 +478,7 @@ bool BytecodeHasNoSideEffect(interpreter::Bytecode bytecode) {
// Literals. // Literals.
case Bytecode::kCreateArrayLiteral: case Bytecode::kCreateArrayLiteral:
case Bytecode::kCreateEmptyArrayLiteral: case Bytecode::kCreateEmptyArrayLiteral:
case Bytecode::kCreateArrayFromIterable:
case Bytecode::kCreateObjectLiteral: case Bytecode::kCreateObjectLiteral:
case Bytecode::kCreateEmptyObjectLiteral: case Bytecode::kCreateEmptyObjectLiteral:
case Bytecode::kCreateRegExpLiteral: case Bytecode::kCreateRegExpLiteral:
......
...@@ -352,11 +352,14 @@ class V8_EXPORT_PRIVATE FeedbackVectorSpec { ...@@ -352,11 +352,14 @@ class V8_EXPORT_PRIVATE FeedbackVectorSpec {
return AddSlot(FeedbackSlotKind::kLoadKeyed); return AddSlot(FeedbackSlotKind::kLoadKeyed);
} }
FeedbackSlot AddStoreICSlot(LanguageMode language_mode) { FeedbackSlotKind GetStoreICSlot(LanguageMode language_mode) {
STATIC_ASSERT(LanguageModeSize == 2); STATIC_ASSERT(LanguageModeSize == 2);
return AddSlot(is_strict(language_mode) return is_strict(language_mode) ? FeedbackSlotKind::kStoreNamedStrict
? FeedbackSlotKind::kStoreNamedStrict : FeedbackSlotKind::kStoreNamedSloppy;
: FeedbackSlotKind::kStoreNamedSloppy); }
FeedbackSlot AddStoreICSlot(LanguageMode language_mode) {
return AddSlot(GetStoreICSlot(language_mode));
} }
FeedbackSlot AddStoreOwnICSlot() { FeedbackSlot AddStoreOwnICSlot() {
......
...@@ -973,6 +973,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral( ...@@ -973,6 +973,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral(
return *this; return *this;
} }
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayFromIterable() {
OutputCreateArrayFromIterable();
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral( BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
size_t constant_properties_entry, int literal_index, int flags, size_t constant_properties_entry, int literal_index, int flags,
Register output) { Register output) {
......
...@@ -234,6 +234,7 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final { ...@@ -234,6 +234,7 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final {
BytecodeArrayBuilder& CreateArrayLiteral(size_t constant_elements_entry, BytecodeArrayBuilder& CreateArrayLiteral(size_t constant_elements_entry,
int literal_index, int flags); int literal_index, int flags);
BytecodeArrayBuilder& CreateEmptyArrayLiteral(int literal_index); BytecodeArrayBuilder& CreateEmptyArrayLiteral(int literal_index);
BytecodeArrayBuilder& CreateArrayFromIterable();
BytecodeArrayBuilder& CreateObjectLiteral(size_t constant_properties_entry, BytecodeArrayBuilder& CreateObjectLiteral(size_t constant_properties_entry,
int literal_index, int flags, int literal_index, int flags,
Register output); Register output);
......
...@@ -2364,116 +2364,6 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -2364,116 +2364,6 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
builder()->LoadAccumulatorWithRegister(literal); builder()->LoadAccumulatorWithRegister(literal);
} }
void BytecodeGenerator::BuildArrayLiteralElementsInsertion(
Register array, int first_spread_index, ZonePtrList<Expression>* elements,
bool skip_constants) {
DCHECK_LT(first_spread_index, elements->length());
Register index = register_allocator()->NewRegister();
int array_index = 0;
ZonePtrList<Expression>::iterator iter = elements->begin();
ZonePtrList<Expression>::iterator first_spread_or_end =
first_spread_index >= 0 ? elements->begin() + first_spread_index
: elements->end();
// Evaluate subexpressions and store them into the array.
SharedFeedbackSlot keyed_store_slot(
feedback_spec(),
feedback_spec()->GetKeyedStoreICSlotKind(language_mode()));
for (; iter != first_spread_or_end; ++iter, array_index++) {
Expression* subexpr = *iter;
DCHECK(!subexpr->IsSpread());
if (skip_constants && subexpr->IsCompileTimeValue()) continue;
builder()
->LoadLiteral(Smi::FromInt(array_index))
.StoreAccumulatorInRegister(index);
VisitForAccumulatorValue(subexpr);
builder()->StoreKeyedProperty(
array, index, feedback_index(keyed_store_slot.Get()), language_mode());
}
if (iter != elements->end()) {
builder()->LoadLiteral(array_index).StoreAccumulatorInRegister(index);
// Handle the first spread element and everything that follows.
FeedbackSlot element_slot = feedback_spec()->AddStoreInArrayLiteralICSlot();
FeedbackSlot index_slot = feedback_spec()->AddBinaryOpICSlot();
// TODO(neis): Only create length_slot when there are holes.
FeedbackSlot length_slot =
feedback_spec()->AddStoreICSlot(LanguageMode::kStrict);
for (; iter != elements->end(); ++iter) {
Expression* subexpr = *iter;
if (subexpr->IsSpread()) {
BuildArrayLiteralSpread(subexpr->AsSpread(), array, index, index_slot,
element_slot);
} else if (!subexpr->IsTheHoleLiteral()) {
// literal[index++] = subexpr
VisitForAccumulatorValue(subexpr);
builder()
->StoreInArrayLiteral(array, index, feedback_index(element_slot))
.LoadAccumulatorWithRegister(index)
.UnaryOperation(Token::INC, feedback_index(index_slot))
.StoreAccumulatorInRegister(index);
} else {
// literal.length = ++index
auto length = ast_string_constants()->length_string();
builder()
->LoadAccumulatorWithRegister(index)
.UnaryOperation(Token::INC, feedback_index(index_slot))
.StoreAccumulatorInRegister(index)
.StoreNamedProperty(array, length, feedback_index(length_slot),
LanguageMode::kStrict);
}
}
}
builder()->LoadAccumulatorWithRegister(array);
}
void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
expr->InitDepthAndFlags();
uint8_t flags = CreateArrayLiteralFlags::Encode(
expr->IsFastCloningSupported(), expr->ComputeFlags());
bool is_empty = expr->is_empty();
bool optimize_as_one_shot = ShouldOptimizeAsOneShot();
size_t entry;
if (is_empty && optimize_as_one_shot) {
entry = builder()->EmptyArrayBoilerplateDescriptionConstantPoolEntry();
} else if (!is_empty) {
entry = builder()->AllocateDeferredConstantPoolEntry();
array_literals_.push_back(std::make_pair(expr, entry));
}
if (optimize_as_one_shot) {
// Create array literal without any allocation sites
RegisterAllocationScope register_scope(this);
RegisterList args = register_allocator()->NewRegisterList(2);
builder()
->LoadConstantPoolEntry(entry)
.StoreAccumulatorInRegister(args[0])
.LoadLiteral(Smi::FromInt(flags))
.StoreAccumulatorInRegister(args[1])
.CallRuntime(Runtime::kCreateArrayLiteralWithoutAllocationSite, args);
} else if (is_empty) {
// Empty array literal fast-path.
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
DCHECK(expr->IsFastCloningSupported());
builder()->CreateEmptyArrayLiteral(literal_index);
return;
} else {
// Deep-copy the literal boilerplate
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
builder()->CreateArrayLiteral(entry, literal_index, flags);
}
Register literal = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(literal);
// Insert all elements except the constant ones, since they are already there.
BuildArrayLiteralElementsInsertion(literal, expr->first_spread_index(),
expr->values(), true);
}
void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread, Register array, void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread, Register array,
Register index, Register index,
FeedbackSlot index_slot, FeedbackSlot index_slot,
...@@ -2513,6 +2403,154 @@ void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread, Register array, ...@@ -2513,6 +2403,154 @@ void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread, Register array,
loop_builder.JumpToHeader(loop_depth_); loop_builder.JumpToHeader(loop_depth_);
} }
void BytecodeGenerator::BuildCreateArrayLiteral(
ZonePtrList<Expression>* elements, ArrayLiteral* expr) {
RegisterAllocationScope register_scope(this);
Register index = register_allocator()->NewRegister();
Register array = register_allocator()->NewRegister();
SharedFeedbackSlot element_slot(feedback_spec(),
FeedbackSlotKind::kStoreInArrayLiteral);
ZonePtrList<Expression>::iterator current = elements->begin();
ZonePtrList<Expression>::iterator end = elements->end();
bool is_empty = elements->is_empty();
if (!is_empty && (*current)->IsSpread()) {
// If we have a leading spread, use CreateArrayFromIterable to create
// an array from it and then add the remaining components to that array.
VisitForAccumulatorValue(*current);
builder()->CreateArrayFromIterable().StoreAccumulatorInRegister(array);
if (++current != end) {
// If there are remaning elements, prepare the index register that is
// used for adding those elements. The next index is the length of the
// newly created array.
auto length = ast_string_constants()->length_string();
int length_load_slot = feedback_index(feedback_spec()->AddLoadICSlot());
builder()
->LoadNamedProperty(array, length, length_load_slot)
.StoreAccumulatorInRegister(index);
}
} else if (expr != nullptr) {
// There are some elements before the first (if any) spread, and we can
// use a boilerplate when creating the initial array from those elements.
// First, allocate a constant pool entry for the boilerplate that will
// be created during finalization, and will contain all the constant
// elements before the first spread. This also handle the empty array case
// and one-shot optimization.
uint8_t flags = CreateArrayLiteralFlags::Encode(
expr->IsFastCloningSupported(), expr->ComputeFlags());
bool optimize_as_one_shot = ShouldOptimizeAsOneShot();
size_t entry;
if (is_empty && optimize_as_one_shot) {
entry = builder()->EmptyArrayBoilerplateDescriptionConstantPoolEntry();
} else if (!is_empty) {
entry = builder()->AllocateDeferredConstantPoolEntry();
array_literals_.push_back(std::make_pair(expr, entry));
}
if (optimize_as_one_shot) {
RegisterList args = register_allocator()->NewRegisterList(2);
builder()
->LoadConstantPoolEntry(entry)
.StoreAccumulatorInRegister(args[0])
.LoadLiteral(Smi::FromInt(flags))
.StoreAccumulatorInRegister(args[1])
.CallRuntime(Runtime::kCreateArrayLiteralWithoutAllocationSite, args);
} else if (is_empty) {
// Empty array literal fast-path.
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
DCHECK(expr->IsFastCloningSupported());
builder()->CreateEmptyArrayLiteral(literal_index);
} else {
// Create array literal from boilerplate.
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
builder()->CreateArrayLiteral(entry, literal_index, flags);
}
builder()->StoreAccumulatorInRegister(array);
// Insert the missing non-constant elements, up until the first spread
// index, into the initial array (the remaining elements will be inserted
// below).
DCHECK_EQ(current, elements->begin());
ZonePtrList<Expression>::iterator first_spread_or_end =
expr->first_spread_index() >= 0 ? current + expr->first_spread_index()
: end;
int array_index = 0;
for (; current != first_spread_or_end; ++current, array_index++) {
Expression* subexpr = *current;
DCHECK(!subexpr->IsSpread());
// Skip the constants.
if (subexpr->IsCompileTimeValue()) continue;
builder()
->LoadLiteral(Smi::FromInt(array_index))
.StoreAccumulatorInRegister(index);
VisitForAccumulatorValue(subexpr);
builder()->StoreInArrayLiteral(array, index,
feedback_index(element_slot.Get()));
}
if (current != end) {
// If there are remaining elements, prepare the index register
// to store the next element, which comes from the first spread.
builder()->LoadLiteral(array_index).StoreAccumulatorInRegister(index);
}
} else {
// In other cases, we prepare an empty array to be filled in below.
DCHECK(!elements->is_empty());
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
builder()
->CreateEmptyArrayLiteral(literal_index)
.StoreAccumulatorInRegister(array);
// Prepare the index for the first element.
builder()->LoadLiteral(Smi::FromInt(0)).StoreAccumulatorInRegister(index);
}
// Now build insertions for the remaining elements from current to end.
SharedFeedbackSlot index_slot(feedback_spec(), FeedbackSlotKind::kBinaryOp);
SharedFeedbackSlot length_slot(
feedback_spec(), feedback_spec()->GetStoreICSlot(LanguageMode::kStrict));
for (; current != end; ++current) {
Expression* subexpr = *current;
if (subexpr->IsSpread()) {
FeedbackSlot real_index_slot = index_slot.Get();
BuildArrayLiteralSpread(subexpr->AsSpread(), array, index,
real_index_slot, element_slot.Get());
} else if (!subexpr->IsTheHoleLiteral()) {
// literal[index++] = subexpr
VisitForAccumulatorValue(subexpr);
builder()
->StoreInArrayLiteral(array, index,
feedback_index(element_slot.Get()))
.LoadAccumulatorWithRegister(index);
// Only increase the index if we are not the last element.
if (current + 1 != end) {
builder()
->UnaryOperation(Token::INC, feedback_index(index_slot.Get()))
.StoreAccumulatorInRegister(index);
}
} else {
// literal.length = ++index
// length_slot is only used when there are holes.
auto length = ast_string_constants()->length_string();
builder()
->LoadAccumulatorWithRegister(index)
.UnaryOperation(Token::INC, feedback_index(index_slot.Get()))
.StoreAccumulatorInRegister(index)
.StoreNamedProperty(array, length, feedback_index(length_slot.Get()),
LanguageMode::kStrict);
}
}
builder()->LoadAccumulatorWithRegister(array);
}
void BytecodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
expr->InitDepthAndFlags();
BuildCreateArrayLiteral(expr->values(), expr);
}
void BytecodeGenerator::VisitStoreInArrayLiteral(StoreInArrayLiteral* expr) { void BytecodeGenerator::VisitStoreInArrayLiteral(StoreInArrayLiteral* expr) {
builder()->SetExpressionAsStatementPosition(expr); builder()->SetExpressionAsStatementPosition(expr);
RegisterAllocationScope register_scope(this); RegisterAllocationScope register_scope(this);
...@@ -3722,17 +3760,12 @@ void BytecodeGenerator::VisitCallSuper(Call* expr) { ...@@ -3722,17 +3760,12 @@ void BytecodeGenerator::VisitCallSuper(Call* expr) {
// mechanism for spreads in array literals. // mechanism for spreads in array literals.
// First generate the array containing all arguments. // First generate the array containing all arguments.
Register array = register_allocator()->NewRegister(); BuildCreateArrayLiteral(args, nullptr);
int literal_index = feedback_index(feedback_spec()->AddLiteralSlot());
builder()
->CreateEmptyArrayLiteral(literal_index)
.StoreAccumulatorInRegister(array);
BuildArrayLiteralElementsInsertion(array, first_spread_index, args, false);
// Now pass that array to %reflect_construct. // Now pass that array to %reflect_construct.
RegisterList construct_args = register_allocator()->NewRegisterList(3); RegisterList construct_args = register_allocator()->NewRegisterList(3);
builder()->StoreAccumulatorInRegister(construct_args[1]);
builder()->MoveRegister(constructor, construct_args[0]); builder()->MoveRegister(constructor, construct_args[0]);
builder()->MoveRegister(array, construct_args[1]);
VisitForRegisterValue(super->new_target_var(), construct_args[2]); VisitForRegisterValue(super->new_target_var(), construct_args[2]);
builder()->CallJSRuntime(Context::REFLECT_CONSTRUCT_INDEX, construct_args); builder()->CallJSRuntime(Context::REFLECT_CONSTRUCT_INDEX, construct_args);
} else { } else {
......
...@@ -183,11 +183,11 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { ...@@ -183,11 +183,11 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildArrayLiteralSpread(Spread* spread, Register array, Register index, void BuildArrayLiteralSpread(Spread* spread, Register array, Register index,
FeedbackSlot index_slot, FeedbackSlot index_slot,
FeedbackSlot element_slot); FeedbackSlot element_slot);
void BuildArrayLiteralElementsInsertion(Register array, // Create Array literals. |expr| can be nullptr, but if provided,
int first_spread_index, // a boilerplate will be used to create an initial array for elements
ZonePtrList<Expression>* elements, // before the first spread.
bool skip_constants); void BuildCreateArrayLiteral(ZonePtrList<Expression>* elements,
ArrayLiteral* expr);
void BuildCreateObjectLiteral(Register literal, uint8_t flags, size_t entry); void BuildCreateObjectLiteral(Register literal, uint8_t flags, size_t entry);
void AllocateTopLevelRegisters(); void AllocateTopLevelRegisters();
void VisitArgumentsObject(Variable* variable); void VisitArgumentsObject(Variable* variable);
......
...@@ -247,6 +247,7 @@ namespace interpreter { ...@@ -247,6 +247,7 @@ namespace interpreter {
OperandType::kIdx, OperandType::kFlag8) \ OperandType::kIdx, OperandType::kFlag8) \
V(CreateArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \ V(CreateArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \
OperandType::kIdx, OperandType::kFlag8) \ OperandType::kIdx, OperandType::kFlag8) \
V(CreateArrayFromIterable, AccumulatorUse::kReadWrite) \
V(CreateEmptyArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx) \ V(CreateEmptyArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx) \
V(CreateObjectLiteral, AccumulatorUse::kNone, OperandType::kIdx, \ V(CreateObjectLiteral, AccumulatorUse::kNone, OperandType::kIdx, \
OperandType::kIdx, OperandType::kFlag8, OperandType::kRegOut) \ OperandType::kIdx, OperandType::kFlag8, OperandType::kRegOut) \
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "src/builtins/builtins-arguments-gen.h" #include "src/builtins/builtins-arguments-gen.h"
#include "src/builtins/builtins-constructor-gen.h" #include "src/builtins/builtins-constructor-gen.h"
#include "src/builtins/builtins-iterator-gen.h"
#include "src/code-events.h" #include "src/code-events.h"
#include "src/code-factory.h" #include "src/code-factory.h"
#include "src/debug/debug.h" #include "src/debug/debug.h"
...@@ -2381,6 +2382,21 @@ IGNITION_HANDLER(CreateEmptyArrayLiteral, InterpreterAssembler) { ...@@ -2381,6 +2382,21 @@ IGNITION_HANDLER(CreateEmptyArrayLiteral, InterpreterAssembler) {
Dispatch(); Dispatch();
} }
// CreateArrayFromIterable
//
// Spread the given iterable from the accumulator into a new JSArray.
IGNITION_HANDLER(CreateArrayFromIterable, InterpreterAssembler) {
Node* iterable = GetAccumulator();
Node* context = GetContext();
IteratorBuiltinsAssembler iterator_assembler(state());
Node* method = iterator_assembler.GetIteratorMethod(context, iterable);
Node* result =
CallBuiltin(Builtins::kIterableToList, context, iterable, method);
SetAccumulator(result);
Dispatch();
}
// CreateObjectLiteral <element_idx> <literal_idx> <flags> // CreateObjectLiteral <element_idx> <literal_idx> <flags>
// //
// Creates an object literal for literal index <literal_idx> with // Creates an object literal for literal index <literal_idx> with
......
...@@ -377,6 +377,7 @@ class ErrorUtils : public AllStatic { ...@@ -377,6 +377,7 @@ class ErrorUtils : public AllStatic {
"% is not a function or its return value is not async iterable") \ "% is not a function or its return value is not async iterable") \
T(NotFiniteNumber, "Value need to be finite number for %()") \ T(NotFiniteNumber, "Value need to be finite number for %()") \
T(NotIterable, "% is not iterable") \ T(NotIterable, "% is not iterable") \
T(NotIterableNoSymbolLoad, "% is not iterable (cannot read property %)") \
T(NotAsyncIterable, "% is not async iterable") \ T(NotAsyncIterable, "% is not async iterable") \
T(NotPropertyName, "% is not a valid property name") \ T(NotPropertyName, "% is not a valid property name") \
T(NotTypedArray, "this is not a typed array.") \ T(NotTypedArray, "this is not a typed array.") \
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "src/parsing/parsing.h" #include "src/parsing/parsing.h"
#include "src/runtime/runtime-utils.h" #include "src/runtime/runtime-utils.h"
#include "src/snapshot/snapshot.h" #include "src/snapshot/snapshot.h"
#include "src/string-builder-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -343,6 +344,31 @@ bool ComputeLocation(Isolate* isolate, MessageLocation* target) { ...@@ -343,6 +344,31 @@ bool ComputeLocation(Isolate* isolate, MessageLocation* target) {
return false; return false;
} }
Handle<String> BuildDefaultCallSite(Isolate* isolate, Handle<Object> object) {
IncrementalStringBuilder builder(isolate);
builder.AppendString(Object::TypeOf(isolate, object));
if (object->IsString()) {
builder.AppendCString(" \"");
builder.AppendString(Handle<String>::cast(object));
builder.AppendCString("\"");
} else if (object->IsNull(isolate)) {
builder.AppendCString(" ");
builder.AppendString(isolate->factory()->null_string());
} else if (object->IsTrue(isolate)) {
builder.AppendCString(" ");
builder.AppendString(isolate->factory()->true_string());
} else if (object->IsFalse(isolate)) {
builder.AppendCString(" ");
builder.AppendString(isolate->factory()->false_string());
} else if (object->IsNumber()) {
builder.AppendCString(" ");
builder.AppendString(isolate->factory()->NumberToString(object));
}
return builder.Finish().ToHandleChecked();
}
Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object, Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object,
CallPrinter::ErrorHint* hint) { CallPrinter::ErrorHint* hint) {
MessageLocation location; MessageLocation location;
...@@ -358,7 +384,7 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object, ...@@ -358,7 +384,7 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object,
isolate->clear_pending_exception(); isolate->clear_pending_exception();
} }
} }
return Object::TypeOf(isolate, object); return BuildDefaultCallSite(isolate, object);
} }
MessageTemplate::Template UpdateErrorTemplate( MessageTemplate::Template UpdateErrorTemplate(
...@@ -388,11 +414,11 @@ MaybeHandle<Object> Runtime::ThrowIteratorError(Isolate* isolate, ...@@ -388,11 +414,11 @@ MaybeHandle<Object> Runtime::ThrowIteratorError(Isolate* isolate,
Handle<Object> object) { Handle<Object> object) {
CallPrinter::ErrorHint hint = CallPrinter::kNone; CallPrinter::ErrorHint hint = CallPrinter::kNone;
Handle<String> callsite = RenderCallSite(isolate, object, &hint); Handle<String> callsite = RenderCallSite(isolate, object, &hint);
MessageTemplate::Template id = MessageTemplate::kNonObjectPropertyLoad; MessageTemplate::Template id = MessageTemplate::kNotIterableNoSymbolLoad;
if (hint == CallPrinter::kNone) { if (hint == CallPrinter::kNone) {
Handle<Symbol> iterator_symbol = isolate->factory()->iterator_symbol(); Handle<Symbol> iterator_symbol = isolate->factory()->iterator_symbol();
THROW_NEW_ERROR(isolate, NewTypeError(id, iterator_symbol, callsite), THROW_NEW_ERROR(isolate, NewTypeError(id, callsite, iterator_symbol),
Object); Object);
} }
...@@ -400,6 +426,14 @@ MaybeHandle<Object> Runtime::ThrowIteratorError(Isolate* isolate, ...@@ -400,6 +426,14 @@ MaybeHandle<Object> Runtime::ThrowIteratorError(Isolate* isolate,
THROW_NEW_ERROR(isolate, NewTypeError(id, callsite), Object); THROW_NEW_ERROR(isolate, NewTypeError(id, callsite), Object);
} }
RUNTIME_FUNCTION(Runtime_ThrowIteratorError) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
RETURN_RESULT_OR_FAILURE(isolate,
Runtime::ThrowIteratorError(isolate, object));
}
RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) { RUNTIME_FUNCTION(Runtime_ThrowCalledNonCallable) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK_EQ(1, args.length()); DCHECK_EQ(1, args.length());
......
...@@ -113,6 +113,7 @@ bool Runtime::IsNonReturning(FunctionId id) { ...@@ -113,6 +113,7 @@ bool Runtime::IsNonReturning(FunctionId id) {
case Runtime::kThrowConstructorReturnedNonObject: case Runtime::kThrowConstructorReturnedNonObject:
case Runtime::kThrowInvalidStringLength: case Runtime::kThrowInvalidStringLength:
case Runtime::kThrowInvalidTypedArrayAlignment: case Runtime::kThrowInvalidTypedArrayAlignment:
case Runtime::kThrowIteratorError:
case Runtime::kThrowIteratorResultNotAnObject: case Runtime::kThrowIteratorResultNotAnObject:
case Runtime::kThrowThrowMethodMissing: case Runtime::kThrowThrowMethodMissing:
case Runtime::kThrowSymbolIteratorInvalid: case Runtime::kThrowSymbolIteratorInvalid:
......
...@@ -264,6 +264,7 @@ namespace internal { ...@@ -264,6 +264,7 @@ namespace internal {
F(ThrowConstructorReturnedNonObject, 0, 1) \ F(ThrowConstructorReturnedNonObject, 0, 1) \
F(ThrowInvalidStringLength, 0, 1) \ F(ThrowInvalidStringLength, 0, 1) \
F(ThrowInvalidTypedArrayAlignment, 2, 1) \ F(ThrowInvalidTypedArrayAlignment, 2, 1) \
F(ThrowIteratorError, 1, 1) \
F(ThrowIteratorResultNotAnObject, 1, 1) \ F(ThrowIteratorResultNotAnObject, 1, 1) \
F(ThrowNotConstructor, 1, 1) \ F(ThrowNotConstructor, 1, 1) \
F(ThrowRangeError, -1 /* >= 1 */, 1) \ F(ThrowRangeError, -1 /* >= 1 */, 1) \
......
...@@ -35,17 +35,17 @@ bytecodes: [ ...@@ -35,17 +35,17 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), I8(1), /* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0), B(Star), R(0),
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(1),
B(LdaZero),
B(Star), R(2), B(Star), R(2),
B(LdaZero),
B(Star), R(1),
B(Ldar), R(0), B(Ldar), R(0),
/* 54 E> */ B(StaKeyedProperty), R(1), R(2), U8(1), /* 54 E> */ B(StaInArrayLiteral), R(2), R(1), U8(1),
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(Star), R(2), B(Star), R(1),
B(Ldar), R(0), B(Ldar), R(0),
/* 59 E> */ B(AddSmi), I8(1), U8(3), /* 59 E> */ B(AddSmi), I8(1), U8(3),
B(StaKeyedProperty), R(1), R(2), U8(1), B(StaInArrayLiteral), R(2), R(1), U8(1),
B(Ldar), R(1), B(Ldar), R(2),
/* 65 S> */ B(Return), /* 65 S> */ B(Return),
] ]
constant pool: [ constant pool: [
...@@ -84,29 +84,29 @@ bytecodes: [ ...@@ -84,29 +84,29 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), I8(1), /* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0), B(Star), R(0),
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(4), /* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(4),
B(Star), R(1),
B(LdaZero),
B(Star), R(2), B(Star), R(2),
B(CreateArrayLiteral), U8(1), U8(1), U8(37),
B(Star), R(3),
B(LdaZero), B(LdaZero),
B(Star), R(1),
B(CreateArrayLiteral), U8(1), U8(1), U8(37),
B(Star), R(4), B(Star), R(4),
B(LdaZero),
B(Star), R(3),
B(Ldar), R(0), B(Ldar), R(0),
/* 56 E> */ B(StaKeyedProperty), R(3), R(4), U8(2), /* 56 E> */ B(StaInArrayLiteral), R(4), R(3), U8(2),
B(Ldar), R(3), B(Ldar), R(4),
B(StaKeyedProperty), R(1), R(2), U8(4), B(StaInArrayLiteral), R(2), R(1), U8(4),
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(Star), R(2), B(Star), R(1),
B(CreateArrayLiteral), U8(2), U8(6), U8(37), B(CreateArrayLiteral), U8(2), U8(6), U8(37),
B(Star), R(3),
B(LdaZero),
B(Star), R(4), B(Star), R(4),
B(LdaZero),
B(Star), R(3),
B(Ldar), R(0), B(Ldar), R(0),
/* 68 E> */ B(AddSmi), I8(2), U8(7), /* 68 E> */ B(AddSmi), I8(2), U8(7),
B(StaKeyedProperty), R(3), R(4), U8(8), B(StaInArrayLiteral), R(4), R(3), U8(8),
B(Ldar), R(3), B(Ldar), R(4),
B(StaKeyedProperty), R(1), R(2), U8(4), B(StaInArrayLiteral), R(2), R(1), U8(4),
B(Ldar), R(1), B(Ldar), R(2),
/* 76 S> */ B(Return), /* 76 S> */ B(Return),
] ]
constant pool: [ constant pool: [
...@@ -121,50 +121,18 @@ handlers: [ ...@@ -121,50 +121,18 @@ handlers: [
snippet: " snippet: "
var a = [ 1, 2 ]; return [ ...a ]; var a = [ 1, 2 ]; return [ ...a ];
" "
frame size: 8 frame size: 1
parameter count: 1 parameter count: 1
bytecode array length: 86 bytecode array length: 9
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(0), B(Star), R(0),
/* 52 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37), /* 52 S> */ B(CreateArrayFromIterable),
B(Star), R(1),
B(LdaConstant), U8(2),
/* 64 S> */ B(Star), R(2),
B(LdaNamedProperty), R(0), U8(3), U8(7),
B(Star), R(7),
B(CallProperty0), R(7), R(0), U8(9),
B(Mov), R(0), R(6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(5),
B(LdaNamedProperty), R(5), U8(4), U8(11),
B(Star), R(4),
B(CallProperty0), R(4), R(5), U8(13),
B(Star), R(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(LdaNamedProperty), R(3), U8(5), U8(15),
B(JumpIfToBooleanTrue), U8(21),
B(LdaNamedProperty), R(3), U8(6), U8(17),
B(Star), R(3),
B(StaInArrayLiteral), R(1), R(2), U8(2),
B(Ldar), R(2),
B(Inc), U8(4),
B(Star), R(2),
B(JumpLoop), U8(35), I8(0),
B(Ldar), R(1),
/* 68 S> */ B(Return), /* 68 S> */ B(Return),
] ]
constant pool: [ constant pool: [
ARRAY_BOILERPLATE_DESCRIPTION_TYPE, ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
Smi [0],
SYMBOL_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
] ]
handlers: [ handlers: [
] ]
...@@ -181,32 +149,32 @@ bytecodes: [ ...@@ -181,32 +149,32 @@ bytecodes: [
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(0), B(Star), R(0),
/* 52 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37), /* 52 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37),
B(Star), R(1), B(Star), R(2),
B(LdaConstant), U8(2), B(LdaConstant), U8(2),
/* 67 S> */ B(Star), R(2), /* 67 S> */ B(Star), R(1),
B(LdaNamedProperty), R(0), U8(3), U8(7), B(LdaNamedProperty), R(0), U8(3), U8(5),
B(Star), R(7), B(Star), R(7),
B(CallProperty0), R(7), R(0), U8(9), B(CallProperty0), R(7), R(0), U8(7),
B(Mov), R(0), R(6), B(Mov), R(0), R(6),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(5), B(Star), R(5),
B(LdaNamedProperty), R(5), U8(4), U8(11), B(LdaNamedProperty), R(5), U8(4), U8(9),
B(Star), R(4), B(Star), R(4),
B(CallProperty0), R(4), R(5), U8(13), B(CallProperty0), R(4), R(5), U8(11),
B(Star), R(3), B(Star), R(3),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(LdaNamedProperty), R(3), U8(5), U8(15), B(LdaNamedProperty), R(3), U8(5), U8(13),
B(JumpIfToBooleanTrue), U8(21), B(JumpIfToBooleanTrue), U8(21),
B(LdaNamedProperty), R(3), U8(6), U8(17), B(LdaNamedProperty), R(3), U8(6), U8(15),
B(Star), R(3), B(Star), R(3),
B(StaInArrayLiteral), R(1), R(2), U8(2), B(StaInArrayLiteral), R(2), R(1), U8(3),
B(Ldar), R(2),
B(Inc), U8(4),
B(Star), R(2),
B(JumpLoop), U8(35), I8(0),
B(Ldar), R(1), B(Ldar), R(1),
B(Inc), U8(2),
B(Star), R(1),
B(JumpLoop), U8(35), I8(0),
B(Ldar), R(2),
/* 71 S> */ B(Return), /* 71 S> */ B(Return),
] ]
constant pool: [ constant pool: [
...@@ -225,55 +193,25 @@ handlers: [ ...@@ -225,55 +193,25 @@ handlers: [
snippet: " snippet: "
var a = [ 1, 2 ]; return [ ...a, 3 ]; var a = [ 1, 2 ]; return [ ...a, 3 ];
" "
frame size: 8 frame size: 3
parameter count: 1 parameter count: 1
bytecode array length: 98 bytecode array length: 25
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(0), B(Star), R(0),
/* 52 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37), /* 52 S> */ B(CreateArrayFromIterable),
B(Star), R(1),
B(LdaConstant), U8(2),
/* 64 S> */ B(Star), R(2),
B(LdaNamedProperty), R(0), U8(3), U8(7),
B(Star), R(7),
B(CallProperty0), R(7), R(0), U8(9),
B(Mov), R(0), R(6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(5),
B(LdaNamedProperty), R(5), U8(4), U8(11),
B(Star), R(4),
B(CallProperty0), R(4), R(5), U8(13),
B(Star), R(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(LdaNamedProperty), R(3), U8(5), U8(15),
B(JumpIfToBooleanTrue), U8(21),
B(LdaNamedProperty), R(3), U8(6), U8(17),
B(Star), R(3),
B(StaInArrayLiteral), R(1), R(2), U8(2),
B(Ldar), R(2),
B(Inc), U8(4),
B(Star), R(2), B(Star), R(2),
B(JumpLoop), U8(35), I8(0), B(LdaNamedProperty), R(2), U8(1), U8(1),
B(Star), R(1),
B(LdaSmi), I8(3), B(LdaSmi), I8(3),
B(StaInArrayLiteral), R(1), R(2), U8(2), B(StaInArrayLiteral), R(2), R(1), U8(3),
B(Ldar), R(2), B(Ldar), R(2),
B(Inc), U8(4),
B(Star), R(2),
B(Ldar), R(1),
/* 71 S> */ B(Return), /* 71 S> */ B(Return),
] ]
constant pool: [ constant pool: [
ARRAY_BOILERPLATE_DESCRIPTION_TYPE, ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
ARRAY_BOILERPLATE_DESCRIPTION_TYPE, ONE_BYTE_INTERNALIZED_STRING_TYPE ["length"],
Smi [0],
SYMBOL_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
] ]
handlers: [ handlers: [
] ]
......
...@@ -362,7 +362,7 @@ bytecodes: [ ...@@ -362,7 +362,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(18), B(Star), R(18),
B(LdaConstant), U8(14), B(LdaConstant), U8(14),
B(Star), R(19), B(Star), R(19),
......
...@@ -67,7 +67,7 @@ snippet: " ...@@ -67,7 +67,7 @@ snippet: "
" "
frame size: 10 frame size: 10
parameter count: 1 parameter count: 1
bytecode array length: 112 bytecode array length: 109
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdaGlobal), U8(0), U8(0), /* 34 S> */ B(LdaGlobal), U8(0), U8(0),
...@@ -75,38 +75,36 @@ bytecodes: [ ...@@ -75,38 +75,36 @@ bytecodes: [
B(LdaNamedProperty), R(0), U8(1), U8(2), B(LdaNamedProperty), R(0), U8(1), U8(2),
B(Star), R(1), B(Star), R(1),
B(CreateArrayLiteral), U8(2), U8(4), U8(37), B(CreateArrayLiteral), U8(2), U8(4), U8(37),
B(Star), R(3),
B(LdaConstant), U8(3),
B(Star), R(4), B(Star), R(4),
/* 49 S> */ B(CreateArrayLiteral), U8(4), U8(10), U8(37), B(LdaConstant), U8(3),
B(Star), R(3),
/* 49 S> */ B(CreateArrayLiteral), U8(4), U8(8), U8(37),
B(Star), R(8), B(Star), R(8),
B(LdaNamedProperty), R(8), U8(5), U8(11), B(LdaNamedProperty), R(8), U8(5), U8(9),
B(Star), R(9), B(Star), R(9),
B(CallProperty0), R(9), R(8), U8(13), B(CallProperty0), R(9), R(8), U8(11),
B(Mov), R(0), R(2), B(Mov), R(0), R(2),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(7), B(Star), R(7),
B(LdaNamedProperty), R(7), U8(6), U8(15), B(LdaNamedProperty), R(7), U8(6), U8(13),
B(Star), R(6), B(Star), R(6),
B(CallProperty0), R(6), R(7), U8(17), B(CallProperty0), R(6), R(7), U8(15),
B(Star), R(5), B(Star), R(5),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
B(LdaNamedProperty), R(5), U8(7), U8(19), B(LdaNamedProperty), R(5), U8(7), U8(17),
B(JumpIfToBooleanTrue), U8(21), B(JumpIfToBooleanTrue), U8(21),
B(LdaNamedProperty), R(5), U8(8), U8(21), B(LdaNamedProperty), R(5), U8(8), U8(19),
B(Star), R(5), B(Star), R(5),
B(StaInArrayLiteral), R(3), R(4), U8(5), B(StaInArrayLiteral), R(4), R(3), U8(6),
B(Ldar), R(4), B(Ldar), R(3),
B(Inc), U8(7), B(Inc), U8(5),
B(Star), R(4), B(Star), R(3),
B(JumpLoop), U8(35), I8(0), B(JumpLoop), U8(35), I8(0),
B(LdaSmi), I8(4), B(LdaSmi), I8(4),
B(StaInArrayLiteral), R(3), R(4), U8(5), B(StaInArrayLiteral), R(4), R(3), U8(6),
B(Ldar), R(4), B(Mov), R(4), R(3),
B(Inc), U8(7),
B(Star), R(4),
B(CallJSRuntime), U8(%reflect_apply), R(1), U8(3), B(CallJSRuntime), U8(%reflect_apply), R(1), U8(3),
B(LdaUndefined), B(LdaUndefined),
/* 64 S> */ B(Return), /* 64 S> */ B(Return),
......
...@@ -123,7 +123,7 @@ bytecodes: [ ...@@ -123,7 +123,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(19), B(Star), R(19),
B(LdaConstant), U8(11), B(LdaConstant), U8(11),
B(Star), R(20), B(Star), R(20),
...@@ -377,7 +377,7 @@ bytecodes: [ ...@@ -377,7 +377,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(19), B(Star), R(19),
B(LdaConstant), U8(11), B(LdaConstant), U8(11),
B(Star), R(20), B(Star), R(20),
...@@ -653,7 +653,7 @@ bytecodes: [ ...@@ -653,7 +653,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(19), B(Star), R(19),
B(LdaConstant), U8(11), B(LdaConstant), U8(11),
B(Star), R(20), B(Star), R(20),
...@@ -885,7 +885,7 @@ bytecodes: [ ...@@ -885,7 +885,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(17), B(Star), R(17),
B(LdaConstant), U8(9), B(LdaConstant), U8(9),
B(Star), R(18), B(Star), R(18),
......
...@@ -85,7 +85,7 @@ bytecodes: [ ...@@ -85,7 +85,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(12), B(Star), R(12),
B(LdaConstant), U8(7), B(LdaConstant), U8(7),
B(Star), R(13), B(Star), R(13),
...@@ -217,7 +217,7 @@ bytecodes: [ ...@@ -217,7 +217,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(13), B(Star), R(13),
B(LdaConstant), U8(7), B(LdaConstant), U8(7),
B(Star), R(14), B(Star), R(14),
...@@ -361,7 +361,7 @@ bytecodes: [ ...@@ -361,7 +361,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(12), B(Star), R(12),
B(LdaConstant), U8(7), B(LdaConstant), U8(7),
B(Star), R(13), B(Star), R(13),
...@@ -495,7 +495,7 @@ bytecodes: [ ...@@ -495,7 +495,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(11), B(Star), R(11),
B(LdaConstant), U8(9), B(LdaConstant), U8(9),
B(Star), R(12), B(Star), R(12),
......
...@@ -89,7 +89,7 @@ bytecodes: [ ...@@ -89,7 +89,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(14), B(Star), R(14),
B(LdaConstant), U8(6), B(LdaConstant), U8(6),
B(Star), R(15), B(Star), R(15),
...@@ -256,7 +256,7 @@ bytecodes: [ ...@@ -256,7 +256,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(14), B(Star), R(14),
B(LdaConstant), U8(11), B(LdaConstant), U8(11),
B(Star), R(15), B(Star), R(15),
...@@ -401,7 +401,7 @@ bytecodes: [ ...@@ -401,7 +401,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(12), B(Star), R(12),
B(LdaConstant), U8(8), B(LdaConstant), U8(8),
B(Star), R(13), B(Star), R(13),
...@@ -550,7 +550,7 @@ bytecodes: [ ...@@ -550,7 +550,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(17), B(Star), R(17),
B(LdaConstant), U8(8), B(LdaConstant), U8(8),
B(Star), R(18), B(Star), R(18),
...@@ -697,7 +697,7 @@ bytecodes: [ ...@@ -697,7 +697,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(15), B(Star), R(15),
B(LdaConstant), U8(9), B(LdaConstant), U8(9),
B(Star), R(16), B(Star), R(16),
...@@ -859,7 +859,7 @@ bytecodes: [ ...@@ -859,7 +859,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(14), B(Star), R(14),
B(LdaConstant), U8(12), B(LdaConstant), U8(12),
B(Star), R(15), B(Star), R(15),
...@@ -1007,7 +1007,7 @@ bytecodes: [ ...@@ -1007,7 +1007,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(20), B(Star), R(20),
B(LdaConstant), U8(6), B(LdaConstant), U8(6),
B(Star), R(21), B(Star), R(21),
...@@ -1218,7 +1218,7 @@ bytecodes: [ ...@@ -1218,7 +1218,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(19), B(Star), R(19),
B(LdaConstant), U8(7), B(LdaConstant), U8(7),
B(Star), R(20), B(Star), R(20),
......
...@@ -203,7 +203,7 @@ bytecodes: [ ...@@ -203,7 +203,7 @@ bytecodes: [
B(TestTypeOf), U8(6), B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
B(Jump), U8(18), B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153), B(Wide), B(LdaSmi), I16(154),
B(Star), R(14), B(Star), R(14),
B(LdaConstant), U8(13), B(LdaConstant), U8(13),
B(Star), R(15), B(Star), R(15),
......
...@@ -343,7 +343,7 @@ snippet: " ...@@ -343,7 +343,7 @@ snippet: "
})(); })();
" "
frame size: 4 frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 32 bytecode array length: 32
bytecodes: [ bytecodes: [
...@@ -351,10 +351,10 @@ bytecodes: [ ...@@ -351,10 +351,10 @@ bytecodes: [
B(Star), R(0), B(Star), R(0),
/* 16 E> */ B(StackCheck), /* 16 E> */ B(StackCheck),
/* 29 S> */ B(LdaConstant), U8(0), /* 29 S> */ B(LdaConstant), U8(0),
B(Star), R(1), B(Star), R(3),
B(LdaSmi), I8(4), B(LdaSmi), I8(4),
B(Star), R(2), B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(1), U8(2), B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(3), U8(2),
/* 31 E> */ B(StaGlobal), U8(1), U8(0), /* 31 E> */ B(StaGlobal), U8(1), U8(0),
/* 60 S> */ B(LdaConstant), U8(2), /* 60 S> */ B(LdaConstant), U8(2),
B(Star), R(3), B(Star), R(3),
...@@ -379,7 +379,7 @@ snippet: " ...@@ -379,7 +379,7 @@ snippet: "
})(); })();
" "
frame size: 4 frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 32 bytecode array length: 32
bytecodes: [ bytecodes: [
...@@ -387,10 +387,10 @@ bytecodes: [ ...@@ -387,10 +387,10 @@ bytecodes: [
B(Star), R(0), B(Star), R(0),
/* 16 E> */ B(StackCheck), /* 16 E> */ B(StackCheck),
/* 29 S> */ B(LdaConstant), U8(0), /* 29 S> */ B(LdaConstant), U8(0),
B(Star), R(1), B(Star), R(3),
B(LdaSmi), I8(37), B(LdaSmi), I8(37),
B(Star), R(2), B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(1), U8(2), B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(3), U8(2),
/* 31 E> */ B(StaGlobal), U8(1), U8(0), /* 31 E> */ B(StaGlobal), U8(1), U8(0),
/* 45 S> */ B(LdaConstant), U8(2), /* 45 S> */ B(LdaConstant), U8(2),
B(Star), R(3), B(Star), R(3),
......
...@@ -86,7 +86,7 @@ snippet: " ...@@ -86,7 +86,7 @@ snippet: "
" "
frame size: 10 frame size: 10
parameter count: 1 parameter count: 1
bytecode array length: 127 bytecode array length: 124
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
B(LdaTheHole), B(LdaTheHole),
...@@ -101,37 +101,35 @@ bytecodes: [ ...@@ -101,37 +101,35 @@ bytecodes: [
B(Mov), R(4), R(0), B(Mov), R(4), R(0),
B(Mov), R(0), R(1), B(Mov), R(0), R(1),
/* 89 S> */ B(CreateArrayLiteral), U8(2), U8(1), U8(37), /* 89 S> */ B(CreateArrayLiteral), U8(2), U8(1), U8(37),
B(Star), R(3),
B(LdaConstant), U8(3),
B(Star), R(4), B(Star), R(4),
/* 101 S> */ B(CreateArrayLiteral), U8(4), U8(7), U8(37), B(LdaConstant), U8(3),
B(Star), R(3),
/* 101 S> */ B(CreateArrayLiteral), U8(4), U8(5), U8(37),
B(Star), R(8), B(Star), R(8),
B(LdaNamedProperty), R(8), U8(5), U8(8), B(LdaNamedProperty), R(8), U8(5), U8(6),
B(Star), R(9), B(Star), R(9),
B(CallProperty0), R(9), R(8), U8(10), B(CallProperty0), R(9), R(8), U8(8),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(7), B(Star), R(7),
B(LdaNamedProperty), R(7), U8(6), U8(12), B(LdaNamedProperty), R(7), U8(6), U8(10),
B(Star), R(6), B(Star), R(6),
B(CallProperty0), R(6), R(7), U8(14), B(CallProperty0), R(6), R(7), U8(12),
B(Star), R(5), B(Star), R(5),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
B(LdaNamedProperty), R(5), U8(7), U8(16), B(LdaNamedProperty), R(5), U8(7), U8(14),
B(JumpIfToBooleanTrue), U8(21), B(JumpIfToBooleanTrue), U8(21),
B(LdaNamedProperty), R(5), U8(8), U8(18), B(LdaNamedProperty), R(5), U8(8), U8(16),
B(Star), R(5), B(Star), R(5),
B(StaInArrayLiteral), R(3), R(4), U8(2), B(StaInArrayLiteral), R(4), R(3), U8(3),
B(Ldar), R(4), B(Ldar), R(3),
B(Inc), U8(4), B(Inc), U8(2),
B(Star), R(4), B(Star), R(3),
B(JumpLoop), U8(35), I8(0), B(JumpLoop), U8(35), I8(0),
B(LdaSmi), I8(4), B(LdaSmi), I8(4),
B(StaInArrayLiteral), R(3), R(4), U8(2), B(StaInArrayLiteral), R(4), R(3), U8(3),
B(Ldar), R(4), B(Mov), R(4), R(3),
B(Inc), U8(4),
B(Star), R(4),
B(CallJSRuntime), U8(%reflect_construct), R(2), U8(2), B(CallJSRuntime), U8(%reflect_construct), R(2), U8(2),
B(LdaUndefined), B(LdaUndefined),
/* 116 S> */ B(Return), /* 116 S> */ B(Return),
......
...@@ -373,16 +373,16 @@ snippet: " ...@@ -373,16 +373,16 @@ snippet: "
a = [1.1, [2.2, 4.5]]; a = [1.1, [2.2, 4.5]];
" "
frame size: 3 frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 20 bytecode array length: 20
bytecodes: [ bytecodes: [
/* 0 E> */ B(StackCheck), /* 0 E> */ B(StackCheck),
/* 7 S> */ B(LdaConstant), U8(0), /* 7 S> */ B(LdaConstant), U8(0),
B(Star), R(1), B(Star), R(3),
B(LdaSmi), I8(4), B(LdaSmi), I8(4),
B(Star), R(2), B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(1), U8(2), B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(3), U8(2),
/* 9 E> */ B(StaGlobal), U8(1), U8(0), /* 9 E> */ B(StaGlobal), U8(1), U8(0),
B(Star), R(0), B(Star), R(0),
/* 36 S> */ B(Return), /* 36 S> */ B(Return),
...@@ -400,16 +400,16 @@ snippet: " ...@@ -400,16 +400,16 @@ snippet: "
b = []; b = [];
" "
frame size: 3 frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 20 bytecode array length: 20
bytecodes: [ bytecodes: [
/* 0 E> */ B(StackCheck), /* 0 E> */ B(StackCheck),
/* 7 S> */ B(LdaConstant), U8(0), /* 7 S> */ B(LdaConstant), U8(0),
B(Star), R(1), B(Star), R(3),
B(LdaSmi), I8(37), B(LdaSmi), I8(37),
B(Star), R(2), B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(1), U8(2), B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(3), U8(2),
/* 9 E> */ B(StaGlobal), U8(1), U8(0), /* 9 E> */ B(StaGlobal), U8(1), U8(0),
B(Star), R(0), B(Star), R(0),
/* 21 S> */ B(Return), /* 21 S> */ B(Return),
......
...@@ -93,7 +93,7 @@ snippet: " ...@@ -93,7 +93,7 @@ snippet: "
" "
frame size: 13 frame size: 13
parameter count: 1 parameter count: 1
bytecode array length: 137 bytecode array length: 130
bytecodes: [ bytecodes: [
B(CreateRestParameter), B(CreateRestParameter),
B(Star), R(2), B(Star), R(2),
...@@ -103,55 +103,51 @@ bytecodes: [ ...@@ -103,55 +103,51 @@ bytecodes: [
/* 140 S> */ B(Ldar), R(closure), /* 140 S> */ B(Ldar), R(closure),
B(GetSuperConstructor), R(5), B(GetSuperConstructor), R(5),
B(CreateEmptyArrayLiteral), U8(0), B(CreateEmptyArrayLiteral), U8(0),
B(Star), R(6),
B(LdaZero),
B(Star), R(7), B(Star), R(7),
B(LdaZero),
B(Star), R(6),
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(StaKeyedProperty), R(6), R(7), U8(1), B(StaInArrayLiteral), R(7), R(6), U8(1),
B(LdaConstant), U8(0), B(Ldar), R(6),
/* 152 S> */ B(Star), R(7), B(Inc), U8(3),
B(LdaNamedProperty), R(2), U8(1), U8(8), /* 152 S> */ B(Star), R(6),
B(LdaNamedProperty), R(2), U8(0), U8(4),
B(Star), R(12), B(Star), R(12),
B(CallProperty0), R(12), R(2), U8(10), B(CallProperty0), R(12), R(2), U8(6),
B(Mov), R(2), R(11), B(Mov), R(2), R(11),
B(Mov), R(1), R(4), B(Mov), R(1), R(4),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(10), B(Star), R(10),
B(LdaNamedProperty), R(10), U8(2), U8(12), B(LdaNamedProperty), R(10), U8(1), U8(8),
B(Star), R(9), B(Star), R(9),
B(CallProperty0), R(9), R(10), U8(14), B(CallProperty0), R(9), R(10), U8(10),
B(Star), R(8), B(Star), R(8),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1),
B(LdaNamedProperty), R(8), U8(3), U8(16), B(LdaNamedProperty), R(8), U8(2), U8(12),
B(JumpIfToBooleanTrue), U8(21), B(JumpIfToBooleanTrue), U8(21),
B(LdaNamedProperty), R(8), U8(4), U8(18), B(LdaNamedProperty), R(8), U8(3), U8(14),
B(Star), R(8), B(Star), R(8),
B(StaInArrayLiteral), R(6), R(7), U8(3), B(StaInArrayLiteral), R(7), R(6), U8(1),
B(Ldar), R(7), B(Ldar), R(6),
B(Inc), U8(5), B(Inc), U8(3),
B(Star), R(7), B(Star), R(6),
B(JumpLoop), U8(35), I8(0), B(JumpLoop), U8(35), I8(0),
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(StaInArrayLiteral), R(6), R(7), U8(3), B(StaInArrayLiteral), R(7), R(6), U8(1),
B(Ldar), R(7), B(Mov), R(5), R(6),
B(Inc), U8(5), B(Mov), R(0), R(8),
B(Star), R(7), /* 140 E> */ B(CallJSRuntime), U8(%reflect_construct), R(6), U8(3),
B(Mov), R(5), R(8), B(Star), R(9),
B(Mov), R(6), R(9),
B(Mov), R(0), R(10),
/* 140 E> */ B(CallJSRuntime), U8(%reflect_construct), R(8), U8(3),
B(Star), R(11),
B(Ldar), R(this), B(Ldar), R(this),
B(ThrowSuperAlreadyCalledIfNotHole), B(ThrowSuperAlreadyCalledIfNotHole),
B(Mov), R(11), R(this), B(Mov), R(9), R(this),
B(Ldar), R(this), B(Ldar), R(this),
B(ThrowSuperNotCalledIfHole), B(ThrowSuperNotCalledIfHole),
/* 162 S> */ B(Return), /* 162 S> */ B(Return),
] ]
constant pool: [ constant pool: [
Smi [1],
SYMBOL_TYPE, SYMBOL_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
......
*%(basename)s:5: TypeError: 1 is not iterable *%(basename)s:5: TypeError: number 1 is not iterable (cannot read property Symbol(Symbol.iterator))
new Map(1); new Map(1);
^ ^
TypeError: 1 is not iterable TypeError: number 1 is not iterable (cannot read property Symbol(Symbol.iterator))
at new Map (<anonymous>) at new Map (<anonymous>)
at *%(basename)s:5:1 at *%(basename)s:5:1
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
*%(basename)s:6: TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined *%(basename)s:6: TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
x[Symbol.iterator]; x[Symbol.iterator];
^ ^
TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
at *%(basename)s:6:2 at *%(basename)s:6:2
...@@ -375,6 +375,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { ...@@ -375,6 +375,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.CreateRegExpLiteral(ast_factory.GetOneByteString("wide_literal"), 0, 0) .CreateRegExpLiteral(ast_factory.GetOneByteString("wide_literal"), 0, 0)
.CreateArrayLiteral(0, 0, 0) .CreateArrayLiteral(0, 0, 0)
.CreateEmptyArrayLiteral(0) .CreateEmptyArrayLiteral(0)
.CreateArrayFromIterable()
.CreateObjectLiteral(0, 0, 0, reg) .CreateObjectLiteral(0, 0, 0, reg)
.CreateEmptyObjectLiteral() .CreateEmptyObjectLiteral()
.CloneObject(reg, 0, 0); .CloneObject(reg, 0, 0);
......
...@@ -28,10 +28,10 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE ...@@ -28,10 +28,10 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS [1].toString() is '1' PASS [1].toString() is '1'
PASS [1].toLocaleString() is 'toLocaleString' PASS [1].toLocaleString() is 'toLocaleString'
FAIL [1].toLocaleString() should be 1. Threw exception TypeError: string is not a function FAIL [1].toLocaleString() should be 1. Threw exception TypeError: string "invalid" is not a function
PASS [/r/].toString() is 'toString2' PASS [/r/].toString() is 'toString2'
PASS [/r/].toLocaleString() is 'toLocaleString2' PASS [/r/].toLocaleString() is 'toLocaleString2'
FAIL [/r/].toLocaleString() should be toString2. Threw exception TypeError: string is not a function FAIL [/r/].toLocaleString() should be toString2. Threw exception TypeError: string "invalid" is not a function
PASS caught is true PASS caught is true
PASS successfullyParsed is true PASS successfullyParsed is true
......
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