Commit 5f8a4272 authored by Hai Dang's avatar Hai Dang Committed by Commit Bot

Reland "[interpreter] Add bytecode for leading array spreads."

This is a reland of 1c48d52b.

It turned out that IterableToList doesn't always behave according to
the ES operation with the same name. Specifically, it allows holey arrays
to take its fast path, which produces an output array with holes where
actually "undefined" elements should appear.

This CL changes the version of IterableToList that is used for spreads
(IterableToListWithSymbolLookup) such that holey arrays take the slow path.
It also includes tests for such situations.

Original change's description:
> [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/1181024
> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Reviewed-by: Georg 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}

Bug: v8:7980
Change-Id: I0b5603a12d2b588327658bf0a9b214bd0f22e237
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Reviewed-on: https://chromium-review.googlesource.com/1201882
Commit-Queue: Hai Dang <dhai@google.com>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55639}
parent fb1687cb
......@@ -551,12 +551,6 @@ bool ObjectLiteral::IsFastCloningSupported() const {
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() {
if (is_initialized()) return depth();
......
......@@ -1478,8 +1478,6 @@ class ArrayLiteral final : public AggregateLiteral {
int first_spread_index() const { return first_spread_index_; }
bool is_empty() const;
// Populate the depth field and flags, returns the depth.
int InitDepthAndFlags();
......
......@@ -1679,10 +1679,12 @@ TF_BUILTIN(ExtractFastJSArray, ArrayBuiltinsAssembler) {
TF_BUILTIN(CloneFastJSArray, ArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
Node* array = Parameter(Descriptor::kSource);
TNode<JSArray> array = CAST(Parameter(Descriptor::kSource));
CSA_ASSERT(this, IsJSArray(array));
CSA_ASSERT(this, Word32BinaryNot(IsNoElementsProtectorCellInvalid()));
CSA_ASSERT(this,
Word32Or(Word32BinaryNot(IsHoleyFastElementsKind(
LoadMapElementsKind(LoadMap(array)))),
Word32BinaryNot(IsNoElementsProtectorCellInvalid())));
ParameterMode mode = OptimalParameterMode();
Return(CloneFastJSArray(context, array, mode));
......
......@@ -325,8 +325,9 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithSpread(
TNode<Object> iterator_fn =
GetProperty(context, spread, IteratorSymbolConstant());
GotoIfNot(TaggedIsCallable(iterator_fn), &if_iterator_fn_not_callable);
TNode<JSArray> list = CAST(
CallBuiltin(Builtins::kIterableToList, context, spread, iterator_fn));
TNode<JSArray> list =
CAST(CallBuiltin(Builtins::kIterableToListMayPreserveHoles, context,
spread, iterator_fn));
var_length = LoadAndUntagToWord32ObjectField(list, JSArray::kLengthOffset);
var_elements = LoadElements(list);
......
......@@ -644,6 +644,11 @@ namespace internal {
TFH(LoadGlobalICInsideTypeofTrampoline, LoadGlobal) \
TFH(CloneObjectIC, CloneObjectWithVector) \
\
/* IterableToList */ \
/* ES #sec-iterabletolist */ \
TFS(IterableToListWithSymbolLookup, kIterable) \
TFS(IterableToListMayPreserveHoles, kIterable, kIteratorFn) \
\
/* Map */ \
TFS(FindOrderedHashMapEntry, kTable, kKey) \
TFJ(MapConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
......@@ -1127,7 +1132,6 @@ namespace internal {
TFJ(SymbolPrototypeValueOf, 0, kReceiver) \
\
/* TypedArray */ \
TFS(IterableToList, kIterable, kIteratorFn) \
TFS(TypedArrayInitialize, kHolder, kLength, kElementSize, kInitialize, \
kBufferConstructor) \
TFS(TypedArrayInitializeWithBuffer, kHolder, kLength, kBuffer, kElementSize, \
......
......@@ -177,10 +177,8 @@ void IntlBuiltinsAssembler::ListFormatCommon(TNode<Context> context,
BIND(&has_list);
{
// 5. Let x be ? IterableToList(list).
IteratorBuiltinsAssembler iterator_assembler(state());
// TODO(adamk): Consider exposing IterableToList as a buitin and calling
// it from here instead of inlining the operation.
TNode<JSArray> x = iterator_assembler.IterableToList(context, list);
TNode<Object> x =
CallBuiltin(Builtins::kIterableToListWithSymbolLookup, context, list);
// 6. Return ? FormatList(lf, x).
args.PopAndReturn(CallRuntime(format_func_id, context, list_format, x));
......
......@@ -5,6 +5,8 @@
#include "src/builtins/builtins-iterator-gen.h"
#include "src/builtins/growable-fixed-array-gen.h"
#include "src/builtins/builtins-utils-gen.h"
#include "src/builtins/builtins.h"
#include "src/heap/factory-inl.h"
namespace v8 {
......@@ -38,8 +40,7 @@ IteratorRecord IteratorBuiltinsAssembler::GetIterator(Node* context,
BIND(&if_not_callable);
{
Node* ret = CallRuntime(Runtime::kThrowTypeError, context,
SmiConstant(MessageTemplate::kNotIterable), object);
Node* ret = CallRuntime(Runtime::kThrowIteratorError, context, object);
GotoIfException(ret, if_exception, exception);
Unreachable();
}
......@@ -197,62 +198,86 @@ void IteratorBuiltinsAssembler::IteratorCloseOnException(
TNode<JSArray> IteratorBuiltinsAssembler::IterableToList(
TNode<Context> context, TNode<Object> iterable, TNode<Object> iterator_fn) {
Label fast_path(this), slow_path(this), done(this);
// 1. Let iteratorRecord be ? GetIterator(items, method).
IteratorRecord iterator_record = GetIterator(context, iterable, iterator_fn);
// 2. Let values be a new empty List.
GrowableFixedArray values(state());
Variable* vars[] = {values.var_array(), values.var_length(),
values.var_capacity()};
Label loop_start(this, 3, vars), done(this);
Goto(&loop_start);
// 3. Let next be true.
// 4. Repeat, while next is not false
BIND(&loop_start);
{
// a. Set next to ? IteratorStep(iteratorRecord).
TNode<Object> next = CAST(IteratorStep(context, iterator_record, &done));
// b. If next is not false, then
// i. Let nextValue be ? IteratorValue(next).
TNode<Object> next_value = CAST(IteratorValue(context, next));
// ii. Append nextValue to the end of the List values.
values.Push(next_value);
Goto(&loop_start);
}
TVARIABLE(JSArray, created_list);
BIND(&done);
return values.ToJSArray(context);
}
Branch(IsFastJSArrayWithNoCustomIteration(iterable, context), &fast_path,
&slow_path);
// This builtin always returns a new JSArray and is thus safe to use even in the
// presence of code that may call back into user-JS. This builtin will take the
// fast path if the iterable is a fast array and the Array prototype and the
// Symbol.iterator is untouched. The fast path skips the iterator and copies the
// backing store to the new array. Note that if the array has holes, the holes
// will be copied to the new array, which is inconsistent with the behavior of
// an actual iteration, where holes should be replaced with undefined (if the
// prototype has no elements). To maintain the correct behavior for holey
// arrays, use the builtin IterableToListWithSymbolLookup.
TF_BUILTIN(IterableToListMayPreserveHoles, IteratorBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable));
TNode<Object> iterator_fn = CAST(Parameter(Descriptor::kIteratorFn));
// This is a fast-path for ignoring the iterator.
BIND(&fast_path);
{
TNode<JSArray> input_array = CAST(iterable);
created_list = CAST(CloneFastJSArray(context, input_array));
Goto(&done);
}
Label slow_path(this);
GotoIfNot(IsFastJSArrayWithNoCustomIteration(iterable, context), &slow_path);
// The fast path will copy holes to the new array.
Return(CallBuiltin(Builtins::kCloneFastJSArray, context, iterable));
BIND(&slow_path);
{
// 1. Let iteratorRecord be ? GetIterator(items, method).
IteratorRecord iterator_record =
GetIterator(context, iterable, iterator_fn);
Return(IterableToList(context, iterable, iterator_fn));
}
// 2. Let values be a new empty List.
GrowableFixedArray values(state());
// This builtin uses the default Symbol.iterator for the iterator, and takes
// the fast path only if the iterable is a fast _packed_ array.
TF_BUILTIN(IterableToListWithSymbolLookup, IteratorBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable));
Variable* vars[] = {values.var_array(), values.var_length(),
values.var_capacity()};
Label loop_start(this, 3, vars), loop_end(this);
Goto(&loop_start);
// 3. Let next be true.
// 4. Repeat, while next is not false
BIND(&loop_start);
{
// a. Set next to ? IteratorStep(iteratorRecord).
TNode<Object> next =
CAST(IteratorStep(context, iterator_record, &loop_end));
// b. If next is not false, then
// i. Let nextValue be ? IteratorValue(next).
TNode<Object> next_value = CAST(IteratorValue(context, next));
// ii. Append nextValue to the end of the List values.
values.Push(next_value);
Goto(&loop_start);
}
BIND(&loop_end);
Label slow_path(this);
created_list = values.ToJSArray(context);
Goto(&done);
}
GotoIfNot(IsFastJSArrayWithNoCustomIteration(iterable, context), &slow_path);
// Here we are guaranteed that iterable is a fast JSArray with an original
// iterator.
Node* map = LoadMap(CAST(iterable));
Node* elements_kind = LoadMapElementsKind(map);
// Take the slow path if the array is holey.
GotoIf(IsHoleyFastElementsKind(elements_kind), &slow_path);
BIND(&done);
return created_list.value();
}
// This is a fast-path for ignoring the iterator. Here we are guaranteed that
// {iterable} is a fast _packed_ JSArray.
Return(CallBuiltin(Builtins::kCloneFastJSArray, context, iterable));
TNode<JSArray> IteratorBuiltinsAssembler::IterableToList(
TNode<Context> context, TNode<Object> iterable) {
TNode<Object> method = GetIteratorMethod(context, iterable);
return IterableToList(context, iterable, method);
BIND(&slow_path);
{
TNode<Object> iterator_fn = GetIteratorMethod(context, iterable);
// TODO(dhai): this is duplicating (generated) code with
// IterableToListMayPreserveHoles. Make IterableToList a builtin.
Return(IterableToList(context, iterable, iterator_fn));
}
}
} // namespace internal
......
......@@ -54,10 +54,11 @@ class IteratorBuiltinsAssembler : public CodeStubAssembler {
void IteratorCloseOnException(Node* context, const IteratorRecord& iterator,
Variable* exception);
// /#sec-iterabletolist
// #sec-iterabletolist
// Build a JSArray by iterating over {iterable} using {iterator_fn},
// following the ECMAscript operation with the same name.
TNode<JSArray> IterableToList(TNode<Context> context, TNode<Object> iterable,
TNode<Object> iterator_fn);
TNode<JSArray> IterableToList(TNode<Context> context, TNode<Object> iterable);
};
} // namespace internal
......
......@@ -5,7 +5,6 @@
#include "src/builtins/builtins-typed-array-gen.h"
#include "src/builtins/builtins-constructor-gen.h"
#include "src/builtins/builtins-iterator-gen.h"
#include "src/builtins/builtins-utils-gen.h"
#include "src/builtins/builtins.h"
#include "src/builtins/growable-fixed-array-gen.h"
......@@ -640,8 +639,9 @@ void TypedArrayBuiltinsAssembler::ConstructByIterable(
Label fast_path(this), slow_path(this), done(this);
CSA_ASSERT(this, IsCallable(iterator_fn));
TNode<JSArray> array_like = CAST(
CallBuiltin(Builtins::kIterableToList, context, iterable, iterator_fn));
TNode<JSArray> array_like =
CAST(CallBuiltin(Builtins::kIterableToListMayPreserveHoles, context,
iterable, iterator_fn));
TNode<Object> initial_length = LoadJSArrayLength(array_like);
TNode<JSFunction> default_constructor = CAST(LoadContextElement(
......@@ -1606,17 +1606,6 @@ TF_BUILTIN(TypedArrayOf, TypedArrayBuiltinsAssembler) {
"%TypedArray%.of");
}
// This builtin always returns a new JSArray and is thus safe to use even in the
// presence of code that may call back into user-JS.
TF_BUILTIN(IterableToList, TypedArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable));
TNode<Object> iterator_fn = CAST(Parameter(Descriptor::kIteratorFn));
IteratorBuiltinsAssembler iterator_assembler(state());
Return(iterator_assembler.IterableToList(context, iterable, iterator_fn));
}
// ES6 #sec-%typedarray%.from
TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
......@@ -1681,8 +1670,9 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
// 7. If usingIterator is not undefined, then
// a. Let values be ? IterableToList(source, usingIterator).
// b. Let len be the number of elements in values.
TNode<JSArray> values = CAST(
CallBuiltin(Builtins::kIterableToList, context, source, iterator_fn));
TNode<JSArray> values =
CAST(CallBuiltin(Builtins::kIterableToListMayPreserveHoles, context,
source, iterator_fn));
// This is not a spec'd limit, so it doesn't particularly matter when we
// throw the range error for typed array length > MaxSmi.
......
......@@ -3965,6 +3965,10 @@ Node* CodeStubAssembler::ExtractFastJSArray(Node* context, Node* array,
Node* CodeStubAssembler::CloneFastJSArray(Node* context, Node* array,
ParameterMode mode,
Node* allocation_site) {
// TODO(dhai): we should be able to assert IsFastJSArray(array) here, but this
// function is also used to copy boilerplates even when the no-elements
// protector is invalid. This function should be renamed to reflect its uses.
CSA_ASSERT(this, IsJSArray(array));
Node* original_array_map = LoadMap(array);
Node* elements_kind = LoadMapElementsKind(original_array_map);
......
......@@ -1601,6 +1601,12 @@ void BytecodeGraphBuilder::VisitCreateEmptyArrayLiteral() {
environment()->BindAccumulator(literal);
}
void BytecodeGraphBuilder::VisitCreateArrayFromIterable() {
Node* iterable = NewNode(javascript()->CreateArrayFromIterable(),
environment()->LookupAccumulator());
environment()->BindAccumulator(iterable, Environment::kAttachFrameState);
}
void BytecodeGraphBuilder::VisitCreateObjectLiteral() {
Handle<ObjectBoilerplateDescription> constant_properties(
ObjectBoilerplateDescription::cast(
......
......@@ -513,6 +513,13 @@ void JSGenericLowering::LowerJSCreateEmptyLiteralArray(Node* node) {
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) {
CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
CallDescriptor::Flags flags = FrameStateFlagForCall(node);
......
......@@ -1190,6 +1190,14 @@ const Operator* JSOperatorBuilder::CreateEmptyLiteralArray(
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(
Handle<ObjectBoilerplateDescription> constant_properties,
VectorSlotPair const& feedback, int literal_flags,
......
......@@ -733,6 +733,7 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
VectorSlotPair const& feedback, int literal_flags,
int number_of_elements);
const Operator* CreateEmptyLiteralArray(VectorSlotPair const& feedback);
const Operator* CreateArrayFromIterable();
const Operator* CreateEmptyLiteralObject();
const Operator* CreateLiteralObject(
......
......@@ -151,6 +151,7 @@
V(JSCreateTypedArray) \
V(JSCreateLiteralArray) \
V(JSCreateEmptyLiteralArray) \
V(JSCreateArrayFromIterable) \
V(JSCreateLiteralObject) \
V(JSCreateEmptyLiteralObject) \
V(JSCloneObject) \
......
......@@ -73,6 +73,7 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
case IrOpcode::kJSCreateArray:
case IrOpcode::kJSCreateTypedArray:
case IrOpcode::kJSCreateLiteralArray:
case IrOpcode::kJSCreateArrayFromIterable:
case IrOpcode::kJSCreateLiteralObject:
case IrOpcode::kJSCreateLiteralRegExp:
case IrOpcode::kJSCreateObject:
......
......@@ -89,6 +89,7 @@ bool NeedsCheckHeapObject(Node* receiver) {
case IrOpcode::kJSCreateIterResultObject:
case IrOpcode::kJSCreateLiteralArray:
case IrOpcode::kJSCreateEmptyLiteralArray:
case IrOpcode::kJSCreateArrayFromIterable:
case IrOpcode::kJSCreateLiteralObject:
case IrOpcode::kJSCreateEmptyLiteralObject:
case IrOpcode::kJSCreateLiteralRegExp:
......
......@@ -1215,6 +1215,10 @@ Type Typer::Visitor::TypeJSCreateEmptyLiteralArray(Node* node) {
return Type::Array();
}
Type Typer::Visitor::TypeJSCreateArrayFromIterable(Node* node) {
return Type::Array();
}
Type Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
return Type::OtherObject();
}
......
......@@ -715,6 +715,10 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
// Type is Array.
CheckTypeIs(node, Type::Array());
break;
case IrOpcode::kJSCreateArrayFromIterable:
// Type is Array.
CheckTypeIs(node, Type::Array());
break;
case IrOpcode::kJSCreateLiteralObject:
case IrOpcode::kJSCreateEmptyLiteralObject:
case IrOpcode::kJSCloneObject:
......
......@@ -279,6 +279,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
V(ReThrow) \
V(ThrowCalledNonCallable) \
V(ThrowInvalidStringLength) \
V(ThrowIteratorError) \
V(ThrowIteratorResultNotAnObject) \
V(ThrowReferenceError) \
V(ThrowSymbolIteratorInvalid) \
......@@ -464,6 +465,7 @@ bool BytecodeHasNoSideEffect(interpreter::Bytecode bytecode) {
// Literals.
case Bytecode::kCreateArrayLiteral:
case Bytecode::kCreateEmptyArrayLiteral:
case Bytecode::kCreateArrayFromIterable:
case Bytecode::kCreateObjectLiteral:
case Bytecode::kCreateEmptyObjectLiteral:
case Bytecode::kCreateRegExpLiteral:
......
......@@ -352,11 +352,14 @@ class V8_EXPORT_PRIVATE FeedbackVectorSpec {
return AddSlot(FeedbackSlotKind::kLoadKeyed);
}
FeedbackSlot AddStoreICSlot(LanguageMode language_mode) {
FeedbackSlotKind GetStoreICSlot(LanguageMode language_mode) {
STATIC_ASSERT(LanguageModeSize == 2);
return AddSlot(is_strict(language_mode)
? FeedbackSlotKind::kStoreNamedStrict
: FeedbackSlotKind::kStoreNamedSloppy);
return is_strict(language_mode) ? FeedbackSlotKind::kStoreNamedStrict
: FeedbackSlotKind::kStoreNamedSloppy;
}
FeedbackSlot AddStoreICSlot(LanguageMode language_mode) {
return AddSlot(GetStoreICSlot(language_mode));
}
FeedbackSlot AddStoreOwnICSlot() {
......
......@@ -973,6 +973,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral(
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayFromIterable() {
OutputCreateArrayFromIterable();
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
size_t constant_properties_entry, int literal_index, int flags,
Register output) {
......
......@@ -234,6 +234,7 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final {
BytecodeArrayBuilder& CreateArrayLiteral(size_t constant_elements_entry,
int literal_index, int flags);
BytecodeArrayBuilder& CreateEmptyArrayLiteral(int literal_index);
BytecodeArrayBuilder& CreateArrayFromIterable();
BytecodeArrayBuilder& CreateObjectLiteral(size_t constant_properties_entry,
int literal_index, int flags,
Register output);
......
This diff is collapsed.
......@@ -183,11 +183,11 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildArrayLiteralSpread(Spread* spread, Register array, Register index,
FeedbackSlot index_slot,
FeedbackSlot element_slot);
void BuildArrayLiteralElementsInsertion(Register array,
int first_spread_index,
ZonePtrList<Expression>* elements,
bool skip_constants);
// Create Array literals. |expr| can be nullptr, but if provided,
// a boilerplate will be used to create an initial array for elements
// before the first spread.
void BuildCreateArrayLiteral(ZonePtrList<Expression>* elements,
ArrayLiteral* expr);
void BuildCreateObjectLiteral(Register literal, uint8_t flags, size_t entry);
void AllocateTopLevelRegisters();
void VisitArgumentsObject(Variable* variable);
......
......@@ -247,6 +247,7 @@ namespace interpreter {
OperandType::kIdx, OperandType::kFlag8) \
V(CreateArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx, \
OperandType::kIdx, OperandType::kFlag8) \
V(CreateArrayFromIterable, AccumulatorUse::kReadWrite) \
V(CreateEmptyArrayLiteral, AccumulatorUse::kWrite, OperandType::kIdx) \
V(CreateObjectLiteral, AccumulatorUse::kNone, OperandType::kIdx, \
OperandType::kIdx, OperandType::kFlag8, OperandType::kRegOut) \
......
......@@ -9,6 +9,7 @@
#include "src/builtins/builtins-arguments-gen.h"
#include "src/builtins/builtins-constructor-gen.h"
#include "src/builtins/builtins-iterator-gen.h"
#include "src/code-events.h"
#include "src/code-factory.h"
#include "src/debug/debug.h"
......@@ -2381,6 +2382,18 @@ IGNITION_HANDLER(CreateEmptyArrayLiteral, InterpreterAssembler) {
Dispatch();
}
// CreateArrayFromIterable
//
// Spread the given iterable from the accumulator into a new JSArray.
IGNITION_HANDLER(CreateArrayFromIterable, InterpreterAssembler) {
Node* iterable = GetAccumulator();
Node* context = GetContext();
Node* result =
CallBuiltin(Builtins::kIterableToListWithSymbolLookup, context, iterable);
SetAccumulator(result);
Dispatch();
}
// CreateObjectLiteral <element_idx> <literal_idx> <flags>
//
// Creates an object literal for literal index <literal_idx> with
......
......@@ -377,6 +377,7 @@ class ErrorUtils : public AllStatic {
"% is not a function or its return value is not async iterable") \
T(NotFiniteNumber, "Value need to be finite number for %()") \
T(NotIterable, "% is not iterable") \
T(NotIterableNoSymbolLoad, "% is not iterable (cannot read property %)") \
T(NotAsyncIterable, "% is not async iterable") \
T(NotPropertyName, "% is not a valid property name") \
T(NotTypedArray, "this is not a typed array.") \
......
......@@ -19,6 +19,7 @@
#include "src/parsing/parsing.h"
#include "src/runtime/runtime-utils.h"
#include "src/snapshot/snapshot.h"
#include "src/string-builder-inl.h"
namespace v8 {
namespace internal {
......@@ -343,6 +344,31 @@ bool ComputeLocation(Isolate* isolate, MessageLocation* target) {
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,
CallPrinter::ErrorHint* hint) {
MessageLocation location;
......@@ -358,7 +384,7 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object,
isolate->clear_pending_exception();
}
}
return Object::TypeOf(isolate, object);
return BuildDefaultCallSite(isolate, object);
}
MessageTemplate::Template UpdateErrorTemplate(
......@@ -388,11 +414,11 @@ MaybeHandle<Object> Runtime::ThrowIteratorError(Isolate* isolate,
Handle<Object> object) {
CallPrinter::ErrorHint hint = CallPrinter::kNone;
Handle<String> callsite = RenderCallSite(isolate, object, &hint);
MessageTemplate::Template id = MessageTemplate::kNonObjectPropertyLoad;
MessageTemplate::Template id = MessageTemplate::kNotIterableNoSymbolLoad;
if (hint == CallPrinter::kNone) {
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);
}
......@@ -400,6 +426,14 @@ MaybeHandle<Object> Runtime::ThrowIteratorError(Isolate* isolate,
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) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
......
......@@ -113,6 +113,7 @@ bool Runtime::IsNonReturning(FunctionId id) {
case Runtime::kThrowConstructorReturnedNonObject:
case Runtime::kThrowInvalidStringLength:
case Runtime::kThrowInvalidTypedArrayAlignment:
case Runtime::kThrowIteratorError:
case Runtime::kThrowIteratorResultNotAnObject:
case Runtime::kThrowThrowMethodMissing:
case Runtime::kThrowSymbolIteratorInvalid:
......
......@@ -258,6 +258,7 @@ namespace internal {
F(ThrowConstructorReturnedNonObject, 0, 1) \
F(ThrowInvalidStringLength, 0, 1) \
F(ThrowInvalidTypedArrayAlignment, 2, 1) \
F(ThrowIteratorError, 1, 1) \
F(ThrowIteratorResultNotAnObject, 1, 1) \
F(ThrowNotConstructor, 1, 1) \
F(ThrowRangeError, -1 /* >= 1 */, 1) \
......
......@@ -35,17 +35,17 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(1),
B(LdaZero),
B(Star), R(2),
B(LdaZero),
B(Star), R(1),
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(Star), R(2),
B(Star), R(1),
B(Ldar), R(0),
/* 59 E> */ B(AddSmi), I8(1), U8(3),
B(StaKeyedProperty), R(1), R(2), U8(1),
B(Ldar), R(1),
B(StaInArrayLiteral), R(2), R(1), U8(1),
B(Ldar), R(2),
/* 65 S> */ B(Return),
]
constant pool: [
......@@ -84,29 +84,29 @@ bytecodes: [
/* 42 S> */ B(LdaSmi), I8(1),
B(Star), R(0),
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(4),
B(Star), R(1),
B(LdaZero),
B(Star), R(2),
B(CreateArrayLiteral), U8(1), U8(1), U8(37),
B(Star), R(3),
B(LdaZero),
B(Star), R(1),
B(CreateArrayLiteral), U8(1), U8(1), U8(37),
B(Star), R(4),
B(LdaZero),
B(Star), R(3),
B(Ldar), R(0),
/* 56 E> */ B(StaKeyedProperty), R(3), R(4), U8(2),
B(Ldar), R(3),
B(StaKeyedProperty), R(1), R(2), U8(4),
/* 56 E> */ B(StaInArrayLiteral), R(4), R(3), U8(2),
B(Ldar), R(4),
B(StaInArrayLiteral), R(2), R(1), U8(4),
B(LdaSmi), I8(1),
B(Star), R(2),
B(Star), R(1),
B(CreateArrayLiteral), U8(2), U8(6), U8(37),
B(Star), R(3),
B(LdaZero),
B(Star), R(4),
B(LdaZero),
B(Star), R(3),
B(Ldar), R(0),
/* 68 E> */ B(AddSmi), I8(2), U8(7),
B(StaKeyedProperty), R(3), R(4), U8(8),
B(Ldar), R(3),
B(StaKeyedProperty), R(1), R(2), U8(4),
B(Ldar), R(1),
B(StaInArrayLiteral), R(4), R(3), U8(8),
B(Ldar), R(4),
B(StaInArrayLiteral), R(2), R(1), U8(4),
B(Ldar), R(2),
/* 76 S> */ B(Return),
]
constant pool: [
......@@ -121,50 +121,18 @@ handlers: [
snippet: "
var a = [ 1, 2 ]; return [ ...a ];
"
frame size: 8
frame size: 1
parameter count: 1
bytecode array length: 86
bytecode array length: 9
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(0),
/* 52 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37),
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),
/* 52 S> */ B(CreateArrayFromIterable),
/* 68 S> */ B(Return),
]
constant pool: [
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: [
]
......@@ -181,32 +149,32 @@ bytecodes: [
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(0),
/* 52 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37),
B(Star), R(1),
B(Star), R(2),
B(LdaConstant), U8(2),
/* 67 S> */ B(Star), R(2),
B(LdaNamedProperty), R(0), U8(3), U8(7),
/* 67 S> */ B(Star), R(1),
B(LdaNamedProperty), R(0), U8(3), U8(5),
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(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(LdaNamedProperty), R(5), U8(4), U8(9),
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(JumpIfJSReceiver), U8(7),
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(LdaNamedProperty), R(3), U8(6), U8(17),
B(LdaNamedProperty), R(3), U8(6), U8(15),
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(StaInArrayLiteral), R(2), R(1), U8(3),
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),
]
constant pool: [
......@@ -225,55 +193,25 @@ handlers: [
snippet: "
var a = [ 1, 2 ]; return [ ...a, 3 ];
"
frame size: 8
frame size: 3
parameter count: 1
bytecode array length: 98
bytecode array length: 25
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(0),
/* 52 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37),
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),
/* 52 S> */ B(CreateArrayFromIterable),
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(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(Ldar), R(1),
/* 71 S> */ B(Return),
]
constant pool: [
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"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["length"],
]
handlers: [
]
......
......@@ -362,7 +362,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(18),
B(LdaConstant), U8(14),
B(Star), R(19),
......
......@@ -67,7 +67,7 @@ snippet: "
"
frame size: 10
parameter count: 1
bytecode array length: 112
bytecode array length: 109
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdaGlobal), U8(0), U8(0),
......@@ -75,38 +75,36 @@ bytecodes: [
B(LdaNamedProperty), R(0), U8(1), U8(2),
B(Star), R(1),
B(CreateArrayLiteral), U8(2), U8(4), U8(37),
B(Star), R(3),
B(LdaConstant), U8(3),
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(LdaNamedProperty), R(8), U8(5), U8(11),
B(LdaNamedProperty), R(8), U8(5), U8(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(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
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(CallProperty0), R(6), R(7), U8(17),
B(CallProperty0), R(6), R(7), U8(15),
B(Star), R(5),
B(JumpIfJSReceiver), U8(7),
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(LdaNamedProperty), R(5), U8(8), U8(21),
B(LdaNamedProperty), R(5), U8(8), U8(19),
B(Star), R(5),
B(StaInArrayLiteral), R(3), R(4), U8(5),
B(Ldar), R(4),
B(Inc), U8(7),
B(Star), R(4),
B(StaInArrayLiteral), R(4), R(3), U8(6),
B(Ldar), R(3),
B(Inc), U8(5),
B(Star), R(3),
B(JumpLoop), U8(35), I8(0),
B(LdaSmi), I8(4),
B(StaInArrayLiteral), R(3), R(4), U8(5),
B(Ldar), R(4),
B(Inc), U8(7),
B(Star), R(4),
B(StaInArrayLiteral), R(4), R(3), U8(6),
B(Mov), R(4), R(3),
B(CallJSRuntime), U8(%reflect_apply), R(1), U8(3),
B(LdaUndefined),
/* 64 S> */ B(Return),
......
......@@ -123,7 +123,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(19),
B(LdaConstant), U8(11),
B(Star), R(20),
......@@ -377,7 +377,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(19),
B(LdaConstant), U8(11),
B(Star), R(20),
......@@ -653,7 +653,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(19),
B(LdaConstant), U8(11),
B(Star), R(20),
......@@ -885,7 +885,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(17),
B(LdaConstant), U8(9),
B(Star), R(18),
......
......@@ -85,7 +85,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(12),
B(LdaConstant), U8(7),
B(Star), R(13),
......@@ -217,7 +217,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(13),
B(LdaConstant), U8(7),
B(Star), R(14),
......@@ -361,7 +361,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(12),
B(LdaConstant), U8(7),
B(Star), R(13),
......@@ -495,7 +495,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(11),
B(LdaConstant), U8(9),
B(Star), R(12),
......
......@@ -89,7 +89,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(14),
B(LdaConstant), U8(6),
B(Star), R(15),
......@@ -256,7 +256,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(14),
B(LdaConstant), U8(11),
B(Star), R(15),
......@@ -401,7 +401,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(12),
B(LdaConstant), U8(8),
B(Star), R(13),
......@@ -550,7 +550,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(17),
B(LdaConstant), U8(8),
B(Star), R(18),
......@@ -697,7 +697,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(15),
B(LdaConstant), U8(9),
B(Star), R(16),
......@@ -859,7 +859,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(14),
B(LdaConstant), U8(12),
B(Star), R(15),
......@@ -1007,7 +1007,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(20),
B(LdaConstant), U8(6),
B(Star), R(21),
......@@ -1218,7 +1218,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(19),
B(LdaConstant), U8(7),
B(Star), R(20),
......
......@@ -203,7 +203,7 @@ bytecodes: [
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(153),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(14),
B(LdaConstant), U8(13),
B(Star), R(15),
......
......@@ -343,7 +343,7 @@ snippet: "
})();
"
frame size: 4
frame size: 5
parameter count: 1
bytecode array length: 32
bytecodes: [
......@@ -351,10 +351,10 @@ bytecodes: [
B(Star), R(0),
/* 16 E> */ B(StackCheck),
/* 29 S> */ B(LdaConstant), U8(0),
B(Star), R(1),
B(Star), R(3),
B(LdaSmi), I8(4),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(1), U8(2),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(3), U8(2),
/* 31 E> */ B(StaGlobal), U8(1), U8(0),
/* 60 S> */ B(LdaConstant), U8(2),
B(Star), R(3),
......@@ -379,7 +379,7 @@ snippet: "
})();
"
frame size: 4
frame size: 5
parameter count: 1
bytecode array length: 32
bytecodes: [
......@@ -387,10 +387,10 @@ bytecodes: [
B(Star), R(0),
/* 16 E> */ B(StackCheck),
/* 29 S> */ B(LdaConstant), U8(0),
B(Star), R(1),
B(Star), R(3),
B(LdaSmi), I8(37),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(1), U8(2),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(3), U8(2),
/* 31 E> */ B(StaGlobal), U8(1), U8(0),
/* 45 S> */ B(LdaConstant), U8(2),
B(Star), R(3),
......
......@@ -86,7 +86,7 @@ snippet: "
"
frame size: 10
parameter count: 1
bytecode array length: 127
bytecode array length: 124
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaTheHole),
......@@ -101,37 +101,35 @@ bytecodes: [
B(Mov), R(4), R(0),
B(Mov), R(0), R(1),
/* 89 S> */ B(CreateArrayLiteral), U8(2), U8(1), U8(37),
B(Star), R(3),
B(LdaConstant), U8(3),
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(LdaNamedProperty), R(8), U8(5), U8(8),
B(LdaNamedProperty), R(8), U8(5), U8(6),
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(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
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(CallProperty0), R(6), R(7), U8(14),
B(CallProperty0), R(6), R(7), U8(12),
B(Star), R(5),
B(JumpIfJSReceiver), U8(7),
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(LdaNamedProperty), R(5), U8(8), U8(18),
B(LdaNamedProperty), R(5), U8(8), U8(16),
B(Star), R(5),
B(StaInArrayLiteral), R(3), R(4), U8(2),
B(Ldar), R(4),
B(Inc), U8(4),
B(Star), R(4),
B(StaInArrayLiteral), R(4), R(3), U8(3),
B(Ldar), R(3),
B(Inc), U8(2),
B(Star), R(3),
B(JumpLoop), U8(35), I8(0),
B(LdaSmi), I8(4),
B(StaInArrayLiteral), R(3), R(4), U8(2),
B(Ldar), R(4),
B(Inc), U8(4),
B(Star), R(4),
B(StaInArrayLiteral), R(4), R(3), U8(3),
B(Mov), R(4), R(3),
B(CallJSRuntime), U8(%reflect_construct), R(2), U8(2),
B(LdaUndefined),
/* 116 S> */ B(Return),
......
......@@ -373,16 +373,16 @@ snippet: "
a = [1.1, [2.2, 4.5]];
"
frame size: 3
frame size: 5
parameter count: 1
bytecode array length: 20
bytecodes: [
/* 0 E> */ B(StackCheck),
/* 7 S> */ B(LdaConstant), U8(0),
B(Star), R(1),
B(Star), R(3),
B(LdaSmi), I8(4),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(1), U8(2),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(3), U8(2),
/* 9 E> */ B(StaGlobal), U8(1), U8(0),
B(Star), R(0),
/* 36 S> */ B(Return),
......@@ -400,16 +400,16 @@ snippet: "
b = [];
"
frame size: 3
frame size: 5
parameter count: 1
bytecode array length: 20
bytecodes: [
/* 0 E> */ B(StackCheck),
/* 7 S> */ B(LdaConstant), U8(0),
B(Star), R(1),
B(Star), R(3),
B(LdaSmi), I8(37),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(1), U8(2),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreateArrayLiteralWithoutAllocationSite), R(3), U8(2),
/* 9 E> */ B(StaGlobal), U8(1), U8(0),
B(Star), R(0),
/* 21 S> */ B(Return),
......
......@@ -93,7 +93,7 @@ snippet: "
"
frame size: 13
parameter count: 1
bytecode array length: 137
bytecode array length: 130
bytecodes: [
B(CreateRestParameter),
B(Star), R(2),
......@@ -103,55 +103,51 @@ bytecodes: [
/* 140 S> */ B(Ldar), R(closure),
B(GetSuperConstructor), R(5),
B(CreateEmptyArrayLiteral), U8(0),
B(Star), R(6),
B(LdaZero),
B(Star), R(7),
B(LdaZero),
B(Star), R(6),
B(LdaSmi), I8(1),
B(StaKeyedProperty), R(6), R(7), U8(1),
B(LdaConstant), U8(0),
/* 152 S> */ B(Star), R(7),
B(LdaNamedProperty), R(2), U8(1), U8(8),
B(StaInArrayLiteral), R(7), R(6), U8(1),
B(Ldar), R(6),
B(Inc), U8(3),
/* 152 S> */ B(Star), R(6),
B(LdaNamedProperty), R(2), U8(0), U8(4),
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(1), R(4),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
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(CallProperty0), R(9), R(10), U8(14),
B(CallProperty0), R(9), R(10), U8(10),
B(Star), R(8),
B(JumpIfJSReceiver), U8(7),
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(LdaNamedProperty), R(8), U8(4), U8(18),
B(LdaNamedProperty), R(8), U8(3), U8(14),
B(Star), R(8),
B(StaInArrayLiteral), R(6), R(7), U8(3),
B(Ldar), R(7),
B(Inc), U8(5),
B(Star), R(7),
B(StaInArrayLiteral), R(7), R(6), U8(1),
B(Ldar), R(6),
B(Inc), U8(3),
B(Star), R(6),
B(JumpLoop), U8(35), I8(0),
B(LdaSmi), I8(1),
B(StaInArrayLiteral), R(6), R(7), U8(3),
B(Ldar), R(7),
B(Inc), U8(5),
B(Star), R(7),
B(Mov), R(5), R(8),
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(StaInArrayLiteral), R(7), R(6), U8(1),
B(Mov), R(5), R(6),
B(Mov), R(0), R(8),
/* 140 E> */ B(CallJSRuntime), U8(%reflect_construct), R(6), U8(3),
B(Star), R(9),
B(Ldar), R(this),
B(ThrowSuperAlreadyCalledIfNotHole),
B(Mov), R(11), R(this),
B(Mov), R(9), R(this),
B(Ldar), R(this),
B(ThrowSuperNotCalledIfHole),
/* 162 S> */ B(Return),
]
constant pool: [
Smi [1],
SYMBOL_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
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);
^
TypeError: 1 is not iterable
TypeError: number 1 is not iterable (cannot read property Symbol(Symbol.iterator))
at new Map (<anonymous>)
at *%(basename)s:5:1
......@@ -2,8 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# 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];
^
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
// Copyright 2018 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.
// Test spreading of holey arrays. Holes should be replaced with undefined.
var a = [, 2];
assertEquals([, 2], [...a]);
assertTrue([...a].hasOwnProperty(0));
assertTrue([2, ...a].hasOwnProperty(1));
class MyArray1 extends Array {
constructor(a) {
super(...a);
}
}
var myarr1 = new MyArray1(a);
assertEquals(undefined, myarr1[0]);
assertTrue(myarr1.hasOwnProperty(0));
class MyArray2 extends Array {
constructor(a) {
super(2, ...a);
}
}
var myarr2 = new MyArray2(a);
assertEquals(undefined, myarr2[1]);
assertTrue(myarr2.hasOwnProperty(1));
function foo0() { return arguments.hasOwnProperty(0); }
assertTrue(foo0(...a));
function foo1() { return arguments.hasOwnProperty(1); }
assertTrue(foo1(2, ...a));
// This test pollutes the Array prototype. No more tests should be run in the
// same instance after this.
a.__proto__[0] = 1;
var arr2 = [...a];
assertEquals([1,2], arr2);
assertTrue(arr2.hasOwnProperty(0));
myarr1 = new MyArray1(a);
assertEquals(1, myarr1[0]);
assertTrue(myarr1.hasOwnProperty(0));
var myarr2 = new MyArray2(a);
assertEquals(1, myarr2[1]);
assertTrue(myarr2.hasOwnProperty(1));
......@@ -375,6 +375,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.CreateRegExpLiteral(ast_factory.GetOneByteString("wide_literal"), 0, 0)
.CreateArrayLiteral(0, 0, 0)
.CreateEmptyArrayLiteral(0)
.CreateArrayFromIterable()
.CreateObjectLiteral(0, 0, 0, reg)
.CreateEmptyObjectLiteral()
.CloneObject(reg, 0, 0);
......
......@@ -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].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/].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 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