| Index: src/builtins/builtins-array-gen.cc
|
| diff --git a/src/builtins/builtins-array-gen.cc b/src/builtins/builtins-array-gen.cc
|
| index abe31e6ce8f7c097f3c9919419791a288ae85912..ca553b73ceb6b643831d5249eec1f6c647c985da 100644
|
| --- a/src/builtins/builtins-array-gen.cc
|
| +++ b/src/builtins/builtins-array-gen.cc
|
| @@ -91,7 +91,8 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
|
|
|
| void FilterResultGenerator() {
|
| // 7. Let A be ArraySpeciesCreate(O, 0).
|
| - a_.Bind(ArraySpeciesCreate(context(), o(), SmiConstant(0)));
|
| + Node* len = SmiConstant(0);
|
| + ArraySpeciesCreate(len);
|
| }
|
|
|
| Node* FilterProcessor(Node* k_value, Node* k) {
|
| @@ -160,37 +161,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
|
| return a();
|
| }
|
|
|
| - void MapResultGenerator() {
|
| - Label runtime(this), done(this, {&a_});
|
| - GotoIf(DoesntHaveInstanceType(o(), JS_ARRAY_TYPE), &runtime);
|
| - Node* o_map = LoadMap(o());
|
| - Node* const initial_array_prototype = LoadContextElement(
|
| - LoadNativeContext(context()), Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
|
| - Node* proto = LoadMapPrototype(o_map);
|
| - GotoIf(WordNotEqual(proto, initial_array_prototype), &runtime);
|
| -
|
| - Node* species_protector = SpeciesProtectorConstant();
|
| - Node* value = LoadObjectField(species_protector, Cell::kValueOffset);
|
| - Node* const protector_invalid = SmiConstant(Isolate::kProtectorInvalid);
|
| - GotoIf(WordEqual(value, protector_invalid), &runtime);
|
| -
|
| - Node* const initial_array_constructor = LoadContextElement(
|
| - LoadNativeContext(context()), Context::ARRAY_FUNCTION_INDEX);
|
| - a_.Bind(ConstructJS(CodeFactory::Construct(isolate()), context(),
|
| - initial_array_constructor, len_));
|
| - Goto(&done);
|
| -
|
| - BIND(&runtime);
|
| - {
|
| - // 5. Let A be ? ArraySpeciesCreate(O, len).
|
| - Node* constructor =
|
| - CallRuntime(Runtime::kArraySpeciesConstructor, context(), o());
|
| - a_.Bind(ConstructJS(CodeFactory::Construct(isolate()), context(),
|
| - constructor, len_));
|
| - Goto(&fully_spec_compliant_);
|
| - }
|
| - BIND(&done);
|
| - }
|
| + void MapResultGenerator() { ArraySpeciesCreate(len_); }
|
|
|
| Node* SpecCompliantMapProcessor(Node* k_value, Node* k) {
|
| // i. Let kValue be ? Get(O, Pk). Performed by the caller of
|
| @@ -716,6 +687,51 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
|
| }
|
| }
|
|
|
| + // Perform ArraySpeciesCreate (ES6 #sec-arrayspeciescreate).
|
| + void ArraySpeciesCreate(Node* len) {
|
| + Label runtime(this, Label::kDeferred), done(this);
|
| +
|
| + Node* const original_map = LoadMap(o());
|
| + GotoIf(Word32NotEqual(LoadMapInstanceType(original_map),
|
| + Int32Constant(JS_ARRAY_TYPE)),
|
| + &runtime);
|
| +
|
| + Node* const native_context = LoadNativeContext(context());
|
| + Node* const initial_array_prototype = LoadContextElement(
|
| + native_context, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
|
| + Node* proto = LoadMapPrototype(original_map);
|
| + GotoIf(WordNotEqual(proto, initial_array_prototype), &runtime);
|
| +
|
| + Node* species_protector = SpeciesProtectorConstant();
|
| + Node* value = LoadObjectField(species_protector, Cell::kValueOffset);
|
| + Node* const protector_invalid = SmiConstant(Isolate::kProtectorInvalid);
|
| + GotoIf(WordEqual(value, protector_invalid), &runtime);
|
| +
|
| + GotoIfNot(TaggedIsPositiveSmi(len), &runtime);
|
| + GotoIf(SmiAbove(len, SmiConstant(JSArray::kInitialMaxFastElementArray)),
|
| + &runtime);
|
| +
|
| + const ElementsKind elements_kind =
|
| + GetHoleyElementsKind(GetInitialFastElementsKind());
|
| + Node* array_map = LoadJSArrayElementsMap(elements_kind, native_context);
|
| + a_.Bind(AllocateJSArray(FAST_SMI_ELEMENTS, array_map, len, len, nullptr,
|
| + CodeStubAssembler::SMI_PARAMETERS));
|
| +
|
| + Goto(&done);
|
| +
|
| + BIND(&runtime);
|
| + {
|
| + // 5. Let A be ? ArraySpeciesCreate(O, len).
|
| + Node* constructor =
|
| + CallRuntime(Runtime::kArraySpeciesConstructor, context(), o());
|
| + a_.Bind(ConstructJS(CodeFactory::Construct(isolate()), context(),
|
| + constructor, len));
|
| + Goto(&fully_spec_compliant_);
|
| + }
|
| +
|
| + BIND(&done);
|
| + }
|
| +
|
| Node* callbackfn_ = nullptr;
|
| Node* o_ = nullptr;
|
| Node* this_arg_ = nullptr;
|
|
|