[cleanup] Drop spread.js for good.
Use IteratorToList to implement CallWithSpread and ConstructWithSpread instead. Bug: v8:7310 Change-Id: Ic1c44cc97914fa4fb92da8c568ac66f3ae78e520 Reviewed-on: https://chromium-review.googlesource.com/956073 Reviewed-by: Peter Marshall <petermarshall@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#51871}
This commit is contained in:
parent
1adc4a66e8
commit
f269570290
1
BUILD.gn
1
BUILD.gn
@ -606,7 +606,6 @@ action("js2c") {
|
||||
"src/js/array.js",
|
||||
"src/js/typedarray.js",
|
||||
"src/js/messages.js",
|
||||
"src/js/spread.js",
|
||||
"src/debug/mirrors.js",
|
||||
"src/debug/debug.js",
|
||||
"src/debug/liveedit.js",
|
||||
|
@ -268,16 +268,21 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructDoubleVarargs(
|
||||
void CallOrConstructBuiltinsAssembler::CallOrConstructWithSpread(
|
||||
Node* target, Node* new_target, Node* spread, Node* args_count,
|
||||
Node* context) {
|
||||
Label if_done(this), if_holey(this), if_runtime(this, Label::kDeferred);
|
||||
Label if_smiorobject(this), if_double(this),
|
||||
if_generic(this, Label::kDeferred);
|
||||
|
||||
VARIABLE(spread_result, MachineRepresentation::kTagged, spread);
|
||||
VARIABLE(var_length, MachineRepresentation::kWord32);
|
||||
VARIABLE(var_elements, MachineRepresentation::kTagged);
|
||||
|
||||
GotoIf(TaggedIsSmi(spread), &if_runtime);
|
||||
GotoIf(TaggedIsSmi(spread), &if_generic);
|
||||
Node* spread_map = LoadMap(spread);
|
||||
GotoIfNot(IsJSArrayMap(spread_map), &if_runtime);
|
||||
GotoIfNot(IsJSArrayMap(spread_map), &if_generic);
|
||||
|
||||
// Check that we have the original Array.prototype.
|
||||
GotoIfNot(IsPrototypeInitialArrayPrototype(context, spread_map), &if_runtime);
|
||||
GotoIfNot(IsPrototypeInitialArrayPrototype(context, spread_map), &if_generic);
|
||||
|
||||
// Check that there are no elements on the Array.prototype chain.
|
||||
GotoIf(IsNoElementsProtectorCellInvalid(), &if_generic);
|
||||
|
||||
// Check that the Array.prototype hasn't been modified in a way that would
|
||||
// affect iteration.
|
||||
@ -285,69 +290,62 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithSpread(
|
||||
DCHECK(isolate()->heap()->array_iterator_protector()->IsPropertyCell());
|
||||
GotoIf(WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset),
|
||||
SmiConstant(Isolate::kProtectorInvalid)),
|
||||
&if_runtime);
|
||||
&if_generic);
|
||||
|
||||
Node* kind = LoadMapElementsKind(spread_map);
|
||||
// The fast-path accesses the {spread} elements directly.
|
||||
var_length.Bind(
|
||||
LoadAndUntagToWord32ObjectField(spread, JSArray::kLengthOffset));
|
||||
var_elements.Bind(LoadObjectField(spread, JSArray::kElementsOffset));
|
||||
|
||||
STATIC_ASSERT(PACKED_SMI_ELEMENTS == 0);
|
||||
STATIC_ASSERT(HOLEY_SMI_ELEMENTS == 1);
|
||||
STATIC_ASSERT(PACKED_ELEMENTS == 2);
|
||||
STATIC_ASSERT(HOLEY_ELEMENTS == 3);
|
||||
STATIC_ASSERT(PACKED_DOUBLE_ELEMENTS == 4);
|
||||
STATIC_ASSERT(HOLEY_DOUBLE_ELEMENTS == 5);
|
||||
STATIC_ASSERT(LAST_FAST_ELEMENTS_KIND == HOLEY_DOUBLE_ELEMENTS);
|
||||
// Check elements kind of {spread}.
|
||||
Node* spread_kind = LoadMapElementsKind(spread_map);
|
||||
GotoIf(Int32LessThan(spread_kind, Int32Constant(PACKED_DOUBLE_ELEMENTS)),
|
||||
&if_smiorobject);
|
||||
Branch(Int32GreaterThan(spread_kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)),
|
||||
&if_generic, &if_double);
|
||||
|
||||
GotoIf(Int32GreaterThan(kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)),
|
||||
&if_runtime);
|
||||
Branch(Word32And(kind, Int32Constant(1)), &if_holey, &if_done);
|
||||
|
||||
// Check the NoElementsProtector cell for holey arrays.
|
||||
BIND(&if_holey);
|
||||
{ Branch(IsNoElementsProtectorCellInvalid(), &if_runtime, &if_done); }
|
||||
|
||||
BIND(&if_runtime);
|
||||
BIND(&if_generic);
|
||||
{
|
||||
Node* spread_iterable = LoadContextElement(LoadNativeContext(context),
|
||||
Context::SPREAD_ITERABLE_INDEX);
|
||||
spread_result.Bind(CallJS(CodeFactory::Call(isolate()), context,
|
||||
spread_iterable, UndefinedConstant(), spread));
|
||||
CSA_ASSERT(this, IsJSArray(spread_result.value()));
|
||||
Goto(&if_done);
|
||||
Label if_iterator_fn_not_callable(this, Label::kDeferred);
|
||||
Node* iterator_fn = GetProperty(context, spread, IteratorSymbolConstant());
|
||||
GotoIf(TaggedIsSmi(iterator_fn), &if_iterator_fn_not_callable);
|
||||
GotoIfNot(IsCallable(iterator_fn), &if_iterator_fn_not_callable);
|
||||
Node* list =
|
||||
CallBuiltin(Builtins::kIterableToList, context, spread, iterator_fn);
|
||||
CSA_ASSERT(this, IsJSArray(list));
|
||||
CSA_ASSERT(this, Word32Equal(LoadMapElementsKind(LoadMap(list)),
|
||||
Int32Constant(PACKED_ELEMENTS)));
|
||||
var_length.Bind(
|
||||
LoadAndUntagToWord32ObjectField(list, JSArray::kLengthOffset));
|
||||
var_elements.Bind(LoadObjectField(list, JSArray::kElementsOffset));
|
||||
Goto(&if_smiorobject);
|
||||
|
||||
BIND(&if_iterator_fn_not_callable);
|
||||
ThrowTypeError(context, MessageTemplate::kIteratorSymbolNonCallable);
|
||||
}
|
||||
|
||||
BIND(&if_done);
|
||||
BIND(&if_smiorobject);
|
||||
{
|
||||
// The result from if_runtime can be an array of doubles.
|
||||
Label if_not_double(this), if_double(this);
|
||||
Node* elements =
|
||||
LoadObjectField(spread_result.value(), JSArray::kElementsOffset);
|
||||
Node* length = LoadAndUntagToWord32ObjectField(spread_result.value(),
|
||||
JSArray::kLengthOffset);
|
||||
Node* const elements = var_elements.value();
|
||||
Node* const length = var_length.value();
|
||||
|
||||
Node* kind = LoadMapElementsKind(LoadMap(elements));
|
||||
CSA_ASSERT(this, Int32LessThanOrEqual(
|
||||
kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)));
|
||||
|
||||
Branch(Int32GreaterThan(kind, Int32Constant(HOLEY_ELEMENTS)), &if_double,
|
||||
&if_not_double);
|
||||
|
||||
BIND(&if_not_double);
|
||||
{
|
||||
if (new_target == nullptr) {
|
||||
Callable callable = CodeFactory::CallVarargs(isolate());
|
||||
TailCallStub(callable, context, target, args_count, elements, length);
|
||||
} else {
|
||||
Callable callable = CodeFactory::ConstructVarargs(isolate());
|
||||
TailCallStub(callable, context, target, new_target, args_count,
|
||||
elements, length);
|
||||
}
|
||||
if (new_target == nullptr) {
|
||||
Callable callable = CodeFactory::CallVarargs(isolate());
|
||||
TailCallStub(callable, context, target, args_count, elements, length);
|
||||
} else {
|
||||
Callable callable = CodeFactory::ConstructVarargs(isolate());
|
||||
TailCallStub(callable, context, target, new_target, args_count, elements,
|
||||
length);
|
||||
}
|
||||
}
|
||||
|
||||
BIND(&if_double);
|
||||
{
|
||||
CallOrConstructDoubleVarargs(target, new_target, elements, length,
|
||||
args_count, context, kind);
|
||||
}
|
||||
BIND(&if_double);
|
||||
{
|
||||
Node* const elements = var_elements.value();
|
||||
Node* const length = var_length.value();
|
||||
|
||||
CallOrConstructDoubleVarargs(target, new_target, elements, length,
|
||||
args_count, context, spread_kind);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,48 +22,49 @@ class StubCache;
|
||||
|
||||
enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
|
||||
|
||||
#define HEAP_CONSTANT_LIST(V) \
|
||||
V(AccessorInfoMap, accessor_info_map, AccessorInfoMap) \
|
||||
V(AccessorPairMap, accessor_pair_map, AccessorPairMap) \
|
||||
V(AllocationSiteMap, allocation_site_map, AllocationSiteMap) \
|
||||
V(BooleanMap, boolean_map, BooleanMap) \
|
||||
V(CodeMap, code_map, CodeMap) \
|
||||
V(EmptyPropertyDictionary, empty_property_dictionary, \
|
||||
EmptyPropertyDictionary) \
|
||||
V(EmptyFixedArray, empty_fixed_array, EmptyFixedArray) \
|
||||
V(EmptySlowElementDictionary, empty_slow_element_dictionary, \
|
||||
EmptySlowElementDictionary) \
|
||||
V(empty_string, empty_string, EmptyString) \
|
||||
V(EmptyWeakCell, empty_weak_cell, EmptyWeakCell) \
|
||||
V(FalseValue, false_value, False) \
|
||||
V(FeedbackVectorMap, feedback_vector_map, FeedbackVectorMap) \
|
||||
V(FixedArrayMap, fixed_array_map, FixedArrayMap) \
|
||||
V(FixedCOWArrayMap, fixed_cow_array_map, FixedCOWArrayMap) \
|
||||
V(FixedDoubleArrayMap, fixed_double_array_map, FixedDoubleArrayMap) \
|
||||
V(FunctionTemplateInfoMap, function_template_info_map, \
|
||||
FunctionTemplateInfoMap) \
|
||||
V(GlobalPropertyCellMap, global_property_cell_map, PropertyCellMap) \
|
||||
V(has_instance_symbol, has_instance_symbol, HasInstanceSymbol) \
|
||||
V(HeapNumberMap, heap_number_map, HeapNumberMap) \
|
||||
V(length_string, length_string, LengthString) \
|
||||
V(ManyClosuresCellMap, many_closures_cell_map, ManyClosuresCellMap) \
|
||||
V(MetaMap, meta_map, MetaMap) \
|
||||
V(MinusZeroValue, minus_zero_value, MinusZero) \
|
||||
V(MutableHeapNumberMap, mutable_heap_number_map, MutableHeapNumberMap) \
|
||||
V(NanValue, nan_value, Nan) \
|
||||
V(NoClosuresCellMap, no_closures_cell_map, NoClosuresCellMap) \
|
||||
V(NullValue, null_value, Null) \
|
||||
V(OneClosureCellMap, one_closure_cell_map, OneClosureCellMap) \
|
||||
V(prototype_string, prototype_string, PrototypeString) \
|
||||
V(SpeciesProtector, species_protector, SpeciesProtector) \
|
||||
V(StoreHandler0Map, store_handler0_map, StoreHandler0Map) \
|
||||
V(SymbolMap, symbol_map, SymbolMap) \
|
||||
V(TheHoleValue, the_hole_value, TheHole) \
|
||||
V(TrueValue, true_value, True) \
|
||||
V(Tuple2Map, tuple2_map, Tuple2Map) \
|
||||
V(Tuple3Map, tuple3_map, Tuple3Map) \
|
||||
V(UndefinedValue, undefined_value, Undefined) \
|
||||
V(WeakCellMap, weak_cell_map, WeakCellMap) \
|
||||
#define HEAP_CONSTANT_LIST(V) \
|
||||
V(AccessorInfoMap, accessor_info_map, AccessorInfoMap) \
|
||||
V(AccessorPairMap, accessor_pair_map, AccessorPairMap) \
|
||||
V(AllocationSiteMap, allocation_site_map, AllocationSiteMap) \
|
||||
V(BooleanMap, boolean_map, BooleanMap) \
|
||||
V(CodeMap, code_map, CodeMap) \
|
||||
V(EmptyPropertyDictionary, empty_property_dictionary, \
|
||||
EmptyPropertyDictionary) \
|
||||
V(EmptyFixedArray, empty_fixed_array, EmptyFixedArray) \
|
||||
V(EmptySlowElementDictionary, empty_slow_element_dictionary, \
|
||||
EmptySlowElementDictionary) \
|
||||
V(empty_string, empty_string, EmptyString) \
|
||||
V(EmptyWeakCell, empty_weak_cell, EmptyWeakCell) \
|
||||
V(FalseValue, false_value, False) \
|
||||
V(FeedbackVectorMap, feedback_vector_map, FeedbackVectorMap) \
|
||||
V(FixedArrayMap, fixed_array_map, FixedArrayMap) \
|
||||
V(FixedCOWArrayMap, fixed_cow_array_map, FixedCOWArrayMap) \
|
||||
V(FixedDoubleArrayMap, fixed_double_array_map, FixedDoubleArrayMap) \
|
||||
V(FunctionTemplateInfoMap, function_template_info_map, \
|
||||
FunctionTemplateInfoMap) \
|
||||
V(GlobalPropertyCellMap, global_property_cell_map, PropertyCellMap) \
|
||||
V(has_instance_symbol, has_instance_symbol, HasInstanceSymbol) \
|
||||
V(HeapNumberMap, heap_number_map, HeapNumberMap) \
|
||||
V(iterator_symbol, iterator_symbol, IteratorSymbol) \
|
||||
V(length_string, length_string, LengthString) \
|
||||
V(ManyClosuresCellMap, many_closures_cell_map, ManyClosuresCellMap) \
|
||||
V(MetaMap, meta_map, MetaMap) \
|
||||
V(MinusZeroValue, minus_zero_value, MinusZero) \
|
||||
V(MutableHeapNumberMap, mutable_heap_number_map, MutableHeapNumberMap) \
|
||||
V(NanValue, nan_value, Nan) \
|
||||
V(NoClosuresCellMap, no_closures_cell_map, NoClosuresCellMap) \
|
||||
V(NullValue, null_value, Null) \
|
||||
V(OneClosureCellMap, one_closure_cell_map, OneClosureCellMap) \
|
||||
V(prototype_string, prototype_string, PrototypeString) \
|
||||
V(SpeciesProtector, species_protector, SpeciesProtector) \
|
||||
V(StoreHandler0Map, store_handler0_map, StoreHandler0Map) \
|
||||
V(SymbolMap, symbol_map, SymbolMap) \
|
||||
V(TheHoleValue, the_hole_value, TheHole) \
|
||||
V(TrueValue, true_value, True) \
|
||||
V(Tuple2Map, tuple2_map, Tuple2Map) \
|
||||
V(Tuple3Map, tuple3_map, Tuple3Map) \
|
||||
V(UndefinedValue, undefined_value, Undefined) \
|
||||
V(WeakCellMap, weak_cell_map, WeakCellMap) \
|
||||
V(SharedFunctionInfoMap, shared_function_info_map, SharedFunctionInfoMap)
|
||||
|
||||
// Returned from IteratorBuiltinsAssembler::GetIterator(). Struct is declared
|
||||
|
@ -57,7 +57,6 @@ enum ContextLookupFlags {
|
||||
V(REFLECT_CONSTRUCT_INDEX, JSFunction, reflect_construct) \
|
||||
V(REFLECT_DEFINE_PROPERTY_INDEX, JSFunction, reflect_define_property) \
|
||||
V(REFLECT_DELETE_PROPERTY_INDEX, JSFunction, reflect_delete_property) \
|
||||
V(SPREAD_ITERABLE_INDEX, JSFunction, spread_iterable) \
|
||||
V(MATH_FLOOR_INDEX, JSFunction, math_floor) \
|
||||
V(MATH_POW_INDEX, JSFunction, math_pow) \
|
||||
V(PROMISE_INTERNAL_CONSTRUCTOR_INDEX, JSFunction, \
|
||||
|
@ -1,34 +0,0 @@
|
||||
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
(function(global, utils) {
|
||||
|
||||
"use strict";
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Imports
|
||||
var InternalArray = utils.InternalArray;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
function SpreadIterable(collection) {
|
||||
if (IS_NULL_OR_UNDEFINED(collection)) {
|
||||
throw %make_type_error(kNotIterable, collection);
|
||||
}
|
||||
|
||||
var args = new InternalArray();
|
||||
for (var value of collection) {
|
||||
args.push(value);
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Exports
|
||||
|
||||
%InstallToContext([
|
||||
"spread_iterable", SpreadIterable,
|
||||
]);
|
||||
|
||||
})
|
@ -618,9 +618,6 @@ TEST(BytecodeGraphBuilderCallRuntime) {
|
||||
{factory->true_value(), BytecodeGraphTester::NewObject("[1, 2, 3]")}},
|
||||
{"function f(arg0) { return %Add(arg0, 2) }\nf(1)",
|
||||
{factory->NewNumberFromInt(5), factory->NewNumberFromInt(3)}},
|
||||
{"function f(arg0) { return %spread_iterable(arg0).length }\nf([])",
|
||||
{factory->NewNumberFromInt(3),
|
||||
BytecodeGraphTester::NewObject("[1, 2, 3]")}},
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < arraysize(snippets); i++) {
|
||||
|
@ -65,24 +65,3 @@ constant pool: [
|
||||
handlers: [
|
||||
]
|
||||
|
||||
---
|
||||
snippet: "
|
||||
function f() { return %spread_iterable([1]) }
|
||||
f();
|
||||
"
|
||||
frame size: 1
|
||||
parameter count: 1
|
||||
bytecode array length: 12
|
||||
bytecodes: [
|
||||
/* 10 E> */ B(StackCheck),
|
||||
/* 15 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
|
||||
B(Star), R(0),
|
||||
B(CallJSRuntime), U8(%spread_iterable), R(0), U8(1),
|
||||
/* 43 S> */ B(Return),
|
||||
]
|
||||
constant pool: [
|
||||
TUPLE2_TYPE,
|
||||
]
|
||||
handlers: [
|
||||
]
|
||||
|
||||
|
@ -601,9 +601,6 @@ TEST(CallRuntime) {
|
||||
|
||||
"function f() { return %Add(1, 2) }\n"
|
||||
"f();\n",
|
||||
|
||||
"function f() { return %spread_iterable([1]) }\n"
|
||||
"f();\n",
|
||||
};
|
||||
|
||||
CHECK(CompareTexts(BuildActual(printer, snippets),
|
||||
|
@ -193,7 +193,7 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
|
||||
.CallUndefinedReceiver(reg, pair, 1)
|
||||
.CallRuntime(Runtime::kIsArray, reg)
|
||||
.CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, reg_list, pair)
|
||||
.CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, reg_list)
|
||||
.CallJSRuntime(Context::OBJECT_IS_FROZEN, reg_list)
|
||||
.CallWithSpread(reg, reg_list, 1);
|
||||
|
||||
// Emit binary operator invocations.
|
||||
|
Loading…
Reference in New Issue
Block a user