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; |