5 #include "src/builtins/builtins-constructor-gen.h" 7 #include "src/ast/ast.h" 8 #include "src/builtins/builtins-call-gen.h" 9 #include "src/builtins/builtins-constructor.h" 10 #include "src/builtins/builtins-utils-gen.h" 11 #include "src/builtins/builtins.h" 12 #include "src/code-factory.h" 13 #include "src/code-stub-assembler.h" 14 #include "src/counters.h" 15 #include "src/interface-descriptors.h" 16 #include "src/macro-assembler.h" 17 #include "src/objects-inl.h" 22 void Builtins::Generate_ConstructVarargs(MacroAssembler* masm) {
23 Generate_CallOrConstructVarargs(masm,
24 BUILTIN_CODE(masm->isolate(), Construct));
27 void Builtins::Generate_ConstructForwardVarargs(MacroAssembler* masm) {
28 Generate_CallOrConstructForwardVarargs(
29 masm, CallOrConstructMode::kConstruct,
30 BUILTIN_CODE(masm->isolate(), Construct));
33 void Builtins::Generate_ConstructFunctionForwardVarargs(MacroAssembler* masm) {
34 Generate_CallOrConstructForwardVarargs(
35 masm, CallOrConstructMode::kConstruct,
36 BUILTIN_CODE(masm->isolate(), ConstructFunction));
39 TF_BUILTIN(ConstructWithArrayLike, CallOrConstructBuiltinsAssembler) {
40 TNode<Object> target = CAST(Parameter(Descriptor::kTarget));
41 SloppyTNode<Object> new_target = CAST(Parameter(Descriptor::kNewTarget));
42 TNode<Object> arguments_list = CAST(Parameter(Descriptor::kArgumentsList));
43 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
44 CallOrConstructWithArrayLike(target, new_target, arguments_list, context);
47 TF_BUILTIN(ConstructWithSpread, CallOrConstructBuiltinsAssembler) {
48 TNode<Object> target = CAST(Parameter(Descriptor::kTarget));
49 SloppyTNode<Object> new_target = CAST(Parameter(Descriptor::kNewTarget));
50 TNode<Object> spread = CAST(Parameter(Descriptor::kSpread));
51 TNode<Int32T> args_count =
52 UncheckedCast<Int32T>(Parameter(Descriptor::kActualArgumentsCount));
53 TNode<Context> context = CAST(Parameter(Descriptor::kContext));
54 CallOrConstructWithSpread(target, new_target, spread, args_count, context);
57 typedef compiler::Node Node;
59 TF_BUILTIN(FastNewClosure, ConstructorBuiltinsAssembler) {
60 Node* shared_function_info = Parameter(Descriptor::kSharedFunctionInfo);
61 Node* feedback_cell = Parameter(Descriptor::kFeedbackCell);
62 Node* context = Parameter(Descriptor::kContext);
64 CSA_ASSERT(
this, IsFeedbackCell(feedback_cell));
65 CSA_ASSERT(
this, IsSharedFunctionInfo(shared_function_info));
67 IncrementCounter(isolate()->counters()->fast_new_closure_total(), 1);
71 Node*
const feedback_cell_map = LoadMap(feedback_cell);
72 Label no_closures(
this), one_closure(
this), cell_done(
this);
74 GotoIf(IsNoFeedbackCellMap(feedback_cell_map), &cell_done);
75 GotoIf(IsNoClosuresCellMap(feedback_cell_map), &no_closures);
76 GotoIf(IsOneClosureCellMap(feedback_cell_map), &one_closure);
77 CSA_ASSERT(
this, IsManyClosuresCellMap(feedback_cell_map),
78 feedback_cell_map, feedback_cell);
82 StoreMapNoWriteBarrier(feedback_cell, RootIndex::kOneClosureCellMap);
86 StoreMapNoWriteBarrier(feedback_cell, RootIndex::kManyClosuresCellMap);
95 LoadObjectField(shared_function_info, SharedFunctionInfo::kFlagsOffset,
96 MachineType::Uint32());
97 Node*
const function_map_index = IntPtrAdd(
98 DecodeWordFromWord32<SharedFunctionInfo::FunctionMapIndexBits>(flags),
99 IntPtrConstant(Context::FIRST_FUNCTION_MAP_INDEX));
100 CSA_ASSERT(
this, UintPtrLessThanOrEqual(
102 IntPtrConstant(Context::LAST_FUNCTION_MAP_INDEX)));
106 Node*
const native_context = LoadNativeContext(context);
107 Node*
const function_map =
108 LoadContextElement(native_context, function_map_index);
111 TNode<IntPtrT> instance_size_in_bytes =
112 TimesPointerSize(LoadMapInstanceSizeInWords(function_map));
113 TNode<Object> result = Allocate(instance_size_in_bytes);
114 StoreMapNoWriteBarrier(result, function_map);
115 InitializeJSObjectBodyNoSlackTracking(result, function_map,
116 instance_size_in_bytes,
117 JSFunction::kSizeWithoutPrototype);
120 StoreObjectFieldRoot(result, JSObject::kPropertiesOrHashOffset,
121 RootIndex::kEmptyFixedArray);
122 StoreObjectFieldRoot(result, JSObject::kElementsOffset,
123 RootIndex::kEmptyFixedArray);
126 Label done(
this), init_prototype(
this);
127 Branch(IsFunctionWithPrototypeSlotMap(function_map), &init_prototype,
130 BIND(&init_prototype);
131 StoreObjectFieldRoot(result, JSFunction::kPrototypeOrInitialMapOffset,
132 RootIndex::kTheHoleValue);
137 STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
138 StoreObjectFieldNoWriteBarrier(result, JSFunction::kFeedbackCellOffset,
140 StoreObjectFieldNoWriteBarrier(result, JSFunction::kSharedFunctionInfoOffset,
141 shared_function_info);
142 StoreObjectFieldNoWriteBarrier(result, JSFunction::kContextOffset, context);
143 Handle<Code> lazy_builtin_handle(
144 isolate()->builtins()->builtin(Builtins::kCompileLazy), isolate());
145 Node* lazy_builtin = HeapConstant(lazy_builtin_handle);
146 StoreObjectFieldNoWriteBarrier(result, JSFunction::kCodeOffset, lazy_builtin);
150 TF_BUILTIN(FastNewObject, ConstructorBuiltinsAssembler) {
151 Node* context = Parameter(Descriptor::kContext);
152 Node* target = Parameter(Descriptor::kTarget);
153 Node* new_target = Parameter(Descriptor::kNewTarget);
155 Label call_runtime(
this);
157 Node* result = EmitFastNewObject(context, target, new_target, &call_runtime);
161 TailCallRuntime(Runtime::kNewObject, context, target, new_target);
164 Node* ConstructorBuiltinsAssembler::EmitFastNewObject(Node* context,
167 VARIABLE(var_obj, MachineRepresentation::kTagged);
168 Label call_runtime(
this), end(
this);
170 Node* result = EmitFastNewObject(context, target, new_target, &call_runtime);
171 var_obj.Bind(result);
175 var_obj.Bind(CallRuntime(Runtime::kNewObject, context, target, new_target));
179 return var_obj.value();
182 Node* ConstructorBuiltinsAssembler::EmitFastNewObject(Node* context,
185 Label* call_runtime) {
186 CSA_ASSERT(
this, HasInstanceType(target, JS_FUNCTION_TYPE));
187 CSA_ASSERT(
this, IsJSReceiver(new_target));
190 Label fast(
this), end(
this);
191 GotoIf(HasInstanceType(new_target, JS_FUNCTION_TYPE), &fast);
198 LoadObjectField(new_target, JSFunction::kPrototypeOrInitialMapOffset);
199 GotoIf(TaggedIsSmi(initial_map), call_runtime);
200 GotoIf(DoesntHaveInstanceType(initial_map, MAP_TYPE), call_runtime);
204 Node* new_target_constructor =
205 LoadObjectField(initial_map, Map::kConstructorOrBackPointerOffset);
206 GotoIf(WordNotEqual(target, new_target_constructor), call_runtime);
208 VARIABLE(properties, MachineRepresentation::kTagged);
210 Label instantiate_map(
this), allocate_properties(
this);
211 GotoIf(IsDictionaryMap(initial_map), &allocate_properties);
213 properties.Bind(EmptyFixedArrayConstant());
214 Goto(&instantiate_map);
216 BIND(&allocate_properties);
218 properties.Bind(AllocateNameDictionary(NameDictionary::kInitialCapacity));
219 Goto(&instantiate_map);
222 BIND(&instantiate_map);
223 return AllocateJSObjectFromMap(initial_map, properties.value(),
nullptr,
224 kNone, kWithSlackTracking);
227 Node* ConstructorBuiltinsAssembler::EmitFastNewFunctionContext(
228 Node* scope_info, Node* slots_uint32, Node* context, ScopeType scope_type) {
229 TNode<IntPtrT> slots = Signed(ChangeUint32ToWord(slots_uint32));
230 TNode<IntPtrT> size = ElementOffsetFromIndex(
231 slots, PACKED_ELEMENTS, INTPTR_PARAMETERS, Context::kTodoHeaderSize);
234 TNode<Context> function_context =
235 UncheckedCast<Context>(AllocateInNewSpace(size));
237 RootIndex context_type;
238 switch (scope_type) {
240 context_type = RootIndex::kEvalContextMap;
243 context_type = RootIndex::kFunctionContextMap;
249 StoreMapNoWriteBarrier(function_context, context_type);
250 TNode<IntPtrT> min_context_slots = IntPtrConstant(Context::MIN_CONTEXT_SLOTS);
252 TNode<IntPtrT> length = IntPtrAdd(slots, min_context_slots);
253 StoreObjectFieldNoWriteBarrier(function_context, Context::kLengthOffset,
255 StoreObjectFieldNoWriteBarrier(function_context, Context::kScopeInfoOffset,
257 StoreObjectFieldNoWriteBarrier(function_context, Context::kPreviousOffset,
259 StoreObjectFieldNoWriteBarrier(function_context, Context::kExtensionOffset,
261 TNode<Context> native_context = LoadNativeContext(context);
262 StoreObjectFieldNoWriteBarrier(function_context,
263 Context::kNativeContextOffset, native_context);
266 TNode<HeapObject> undefined = UndefinedConstant();
267 TNode<IntPtrT> start_offset = IntPtrConstant(Context::kTodoHeaderSize);
268 CodeStubAssembler::VariableList vars(0, zone());
270 vars, start_offset, size,
272 StoreObjectFieldNoWriteBarrier(
273 function_context, UncheckedCast<IntPtrT>(offset), undefined);
275 kTaggedSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
276 return function_context;
279 TF_BUILTIN(FastNewFunctionContextEval, ConstructorBuiltinsAssembler) {
280 Node* scope_info = Parameter(Descriptor::kScopeInfo);
281 Node* slots = Parameter(Descriptor::kSlots);
282 Node* context = Parameter(Descriptor::kContext);
283 Return(EmitFastNewFunctionContext(scope_info, slots, context,
284 ScopeType::EVAL_SCOPE));
287 TF_BUILTIN(FastNewFunctionContextFunction, ConstructorBuiltinsAssembler) {
288 Node* scope_info = Parameter(Descriptor::kScopeInfo);
289 Node* slots = Parameter(Descriptor::kSlots);
290 Node* context = Parameter(Descriptor::kContext);
291 Return(EmitFastNewFunctionContext(scope_info, slots, context,
292 ScopeType::FUNCTION_SCOPE));
295 Node* ConstructorBuiltinsAssembler::EmitCreateRegExpLiteral(
296 Node* feedback_vector, Node* slot, Node* pattern, Node* flags,
298 Label call_runtime(
this, Label::kDeferred), end(
this);
300 VARIABLE(result, MachineRepresentation::kTagged);
301 TNode<Object> literal_site =
302 CAST(LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS));
303 GotoIf(NotHasBoilerplate(literal_site), &call_runtime);
305 Node* boilerplate = literal_site;
306 CSA_ASSERT(
this, IsJSRegExp(boilerplate));
307 int size = JSRegExp::kSize + JSRegExp::kInObjectFieldCount * kPointerSize;
308 Node* copy = Allocate(size);
309 for (
int offset = 0; offset < size; offset += kPointerSize) {
310 Node* value = LoadObjectField(boilerplate, offset);
311 StoreObjectFieldNoWriteBarrier(copy, offset, value);
319 result.Bind(CallRuntime(Runtime::kCreateRegExpLiteral, context,
320 feedback_vector, SmiTag(slot), pattern, flags));
325 return result.value();
328 TF_BUILTIN(CreateRegExpLiteral, ConstructorBuiltinsAssembler) {
329 Node* feedback_vector = Parameter(Descriptor::kFeedbackVector);
330 Node* slot = SmiUntag(Parameter(Descriptor::kSlot));
331 Node* pattern = Parameter(Descriptor::kPattern);
332 Node* flags = Parameter(Descriptor::kFlags);
333 Node* context = Parameter(Descriptor::kContext);
335 EmitCreateRegExpLiteral(feedback_vector, slot, pattern, flags, context);
339 Node* ConstructorBuiltinsAssembler::EmitCreateShallowArrayLiteral(
340 Node* feedback_vector, Node* slot, Node* context, Label* call_runtime,
341 AllocationSiteMode allocation_site_mode) {
342 Label zero_capacity(
this), cow_elements(
this), fast_elements(
this),
344 VARIABLE(result, MachineRepresentation::kTagged);
346 TNode<Object> maybe_allocation_site =
347 CAST(LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS));
348 GotoIf(NotHasBoilerplate(maybe_allocation_site), call_runtime);
350 TNode<AllocationSite> allocation_site = CAST(maybe_allocation_site);
351 TNode<JSArray> boilerplate = CAST(LoadBoilerplate(allocation_site));
353 ParameterMode mode = OptimalParameterMode();
354 if (allocation_site_mode == TRACK_ALLOCATION_SITE) {
355 return CloneFastJSArray(context, boilerplate, mode, allocation_site);
357 return CloneFastJSArray(context, boilerplate, mode);
361 TF_BUILTIN(CreateShallowArrayLiteral, ConstructorBuiltinsAssembler) {
362 Node* feedback_vector = Parameter(Descriptor::kFeedbackVector);
363 Node* slot = SmiUntag(Parameter(Descriptor::kSlot));
364 Node* constant_elements = Parameter(Descriptor::kConstantElements);
365 Node* context = Parameter(Descriptor::kContext);
366 Label call_runtime(
this, Label::kDeferred);
367 Return(EmitCreateShallowArrayLiteral(feedback_vector, slot, context,
369 DONT_TRACK_ALLOCATION_SITE));
373 Comment(
"call runtime");
375 AggregateLiteral::kDisableMementos | AggregateLiteral::kIsShallow;
376 Return(CallRuntime(Runtime::kCreateArrayLiteral, context, feedback_vector,
377 SmiTag(slot), constant_elements, SmiConstant(flags)));
381 Node* ConstructorBuiltinsAssembler::EmitCreateEmptyArrayLiteral(
382 Node* feedback_vector, Node* slot, Node* context) {
385 TNode<Object> maybe_allocation_site =
386 CAST(LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS));
387 TVARIABLE(AllocationSite, allocation_site);
389 Label create_empty_array(
this),
390 initialize_allocation_site(
this, Label::kDeferred), done(
this);
391 GotoIf(TaggedIsSmi(maybe_allocation_site), &initialize_allocation_site);
393 allocation_site = CAST(maybe_allocation_site);
394 Goto(&create_empty_array);
397 BIND(&initialize_allocation_site);
400 CreateAllocationSiteInFeedbackVector(feedback_vector, SmiTag(slot));
401 Goto(&create_empty_array);
404 BIND(&create_empty_array);
405 TNode<Int32T> kind = LoadElementsKind(allocation_site.value());
406 TNode<Context> native_context = LoadNativeContext(context);
407 Comment(
"LoadJSArrayElementsMap");
408 TNode<Map> array_map = LoadJSArrayElementsMap(kind, native_context);
409 TNode<Smi> zero = SmiConstant(0);
410 Comment(
"Allocate JSArray");
411 TNode<JSArray> result =
412 AllocateJSArray(GetInitialFastElementsKind(), array_map, zero, zero,
413 allocation_site.value(), ParameterMode::SMI_PARAMETERS);
421 TF_BUILTIN(CreateEmptyArrayLiteral, ConstructorBuiltinsAssembler) {
422 Node* feedback_vector = Parameter(Descriptor::kFeedbackVector);
423 Node* slot = SmiUntag(Parameter(Descriptor::kSlot));
424 Node* context = Parameter(Descriptor::kContext);
425 Node* result = EmitCreateEmptyArrayLiteral(feedback_vector, slot, context);
429 Node* ConstructorBuiltinsAssembler::EmitCreateShallowObjectLiteral(
430 Node* feedback_vector, Node* slot, Label* call_runtime) {
431 TNode<Object> maybe_allocation_site =
432 CAST(LoadFeedbackVectorSlot(feedback_vector, slot, 0, INTPTR_PARAMETERS));
433 GotoIf(NotHasBoilerplate(maybe_allocation_site), call_runtime);
435 TNode<AllocationSite> allocation_site = CAST(maybe_allocation_site);
436 TNode<JSObject> boilerplate = LoadBoilerplate(allocation_site);
437 TNode<Map> boilerplate_map = LoadMap(boilerplate);
438 CSA_ASSERT(
this, IsJSObjectMap(boilerplate_map));
440 VARIABLE(var_properties, MachineRepresentation::kTagged);
442 Node* bit_field_3 = LoadMapBitField3(boilerplate_map);
443 GotoIf(IsSetWord32<Map::IsDeprecatedBit>(bit_field_3), call_runtime);
445 Label if_dictionary(
this), if_fast(
this), done(
this);
446 Branch(IsSetWord32<Map::IsDictionaryMapBit>(bit_field_3), &if_dictionary,
448 BIND(&if_dictionary);
450 Comment(
"Copy dictionary properties");
451 var_properties.Bind(CopyNameDictionary(
452 CAST(LoadSlowProperties(boilerplate)), call_runtime));
459 Node* boilerplate_properties = LoadFastProperties(boilerplate);
460 GotoIfNot(IsEmptyFixedArray(boilerplate_properties), call_runtime);
461 var_properties.Bind(EmptyFixedArrayConstant());
467 VARIABLE(var_elements, MachineRepresentation::kTagged);
470 Label if_empty_fixed_array(
this), if_copy_elements(
this), done(
this);
471 Node* boilerplate_elements = LoadElements(boilerplate);
472 Branch(IsEmptyFixedArray(boilerplate_elements), &if_empty_fixed_array,
475 BIND(&if_empty_fixed_array);
476 var_elements.Bind(boilerplate_elements);
479 BIND(&if_copy_elements);
480 CSA_ASSERT(
this, Word32BinaryNot(
481 IsFixedCOWArrayMap(LoadMap(boilerplate_elements))));
482 ExtractFixedArrayFlags flags;
483 flags |= ExtractFixedArrayFlag::kAllFixedArrays;
484 flags |= ExtractFixedArrayFlag::kNewSpaceAllocationOnly;
485 flags |= ExtractFixedArrayFlag::kDontCopyCOW;
486 var_elements.Bind(CloneFixedArray(boilerplate_elements, flags));
493 STATIC_ASSERT(JSObject::kMaxInstanceSize < kMaxRegularHeapObjectSize);
494 TNode<IntPtrT> instance_size =
495 TimesPointerSize(LoadMapInstanceSizeInWords(boilerplate_map));
496 TNode<IntPtrT> allocation_size = instance_size;
497 bool needs_allocation_memento = FLAG_allocation_site_pretenuring;
498 if (needs_allocation_memento) {
501 IntPtrAdd(instance_size, IntPtrConstant(AllocationMemento::kSize));
504 TNode<HeapObject> copy =
505 UncheckedCast<HeapObject>(AllocateInNewSpace(allocation_size));
507 Comment(
"Initialize Literal Copy");
509 StoreMapNoWriteBarrier(copy, boilerplate_map);
510 StoreObjectFieldNoWriteBarrier(copy, JSObject::kPropertiesOrHashOffset,
511 var_properties.value());
512 StoreObjectFieldNoWriteBarrier(copy, JSObject::kElementsOffset,
513 var_elements.value());
518 if (needs_allocation_memento) {
519 InitializeAllocationMemento(copy, instance_size, allocation_site);
524 Label continue_with_write_barrier(
this), done_init(
this);
525 TVARIABLE(IntPtrT, offset, IntPtrConstant(JSObject::kHeaderSize));
527 bool may_use_mutable_heap_numbers = !FLAG_unbox_double_fields;
529 Comment(
"Copy in-object properties fast");
530 Label continue_fast(
this, &offset);
531 Branch(WordEqual(offset.value(), instance_size), &done_init,
533 BIND(&continue_fast);
534 if (may_use_mutable_heap_numbers) {
535 TNode<Object> field = LoadObjectField(boilerplate, offset.value());
536 Label store_field(
this);
537 GotoIf(TaggedIsSmi(field), &store_field);
538 GotoIf(IsMutableHeapNumber(CAST(field)), &continue_with_write_barrier);
541 StoreObjectFieldNoWriteBarrier(copy, offset.value(), field);
544 TNode<IntPtrT> field =
545 LoadObjectField<IntPtrT>(boilerplate, offset.value());
546 StoreObjectFieldNoWriteBarrier(copy, offset.value(), field);
548 offset = IntPtrAdd(offset.value(), IntPtrConstant(kPointerSize));
549 Branch(WordNotEqual(offset.value(), instance_size), &continue_fast,
553 if (!may_use_mutable_heap_numbers) {
561 BIND(&continue_with_write_barrier);
563 Comment(
"Copy in-object properties slow");
564 BuildFastLoop(offset.value(), instance_size,
566 Node* field = LoadObjectField(boilerplate, offset);
567 StoreObjectFieldNoWriteBarrier(copy, offset, field);
569 kPointerSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
570 Comment(
"Copy mutable HeapNumber values");
571 BuildFastLoop(offset.value(), instance_size,
573 Node* field = LoadObjectField(copy, offset);
574 Label copy_mutable_heap_number(
this, Label::kDeferred),
577 GotoIf(TaggedIsSmi(field), &continue_loop);
578 Branch(IsMutableHeapNumber(field),
579 ©_mutable_heap_number, &continue_loop);
580 BIND(©_mutable_heap_number);
582 Node* double_value = LoadHeapNumberValue(field);
583 Node* mutable_heap_number =
584 AllocateMutableHeapNumberWithValue(double_value);
585 StoreObjectField(copy, offset, mutable_heap_number);
586 Goto(&continue_loop);
588 BIND(&continue_loop);
590 kPointerSize, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
598 TF_BUILTIN(CreateShallowObjectLiteral, ConstructorBuiltinsAssembler) {
599 Label call_runtime(
this);
600 Node* feedback_vector = Parameter(Descriptor::kFeedbackVector);
601 Node* slot = SmiUntag(Parameter(Descriptor::kSlot));
603 EmitCreateShallowObjectLiteral(feedback_vector, slot, &call_runtime);
607 Node* object_boilerplate_description =
608 Parameter(Descriptor::kObjectBoilerplateDescription);
609 Node* flags = Parameter(Descriptor::kFlags);
610 Node* context = Parameter(Descriptor::kContext);
611 TailCallRuntime(Runtime::kCreateObjectLiteral, context, feedback_vector,
612 SmiTag(slot), object_boilerplate_description, flags);
616 Node* ConstructorBuiltinsAssembler::EmitCreateEmptyObjectLiteral(
618 Node* native_context = LoadNativeContext(context);
619 Node* object_function =
620 LoadContextElement(native_context, Context::OBJECT_FUNCTION_INDEX);
621 Node* map = LoadObjectField(object_function,
622 JSFunction::kPrototypeOrInitialMapOffset);
623 CSA_ASSERT(
this, IsMap(map));
625 STATIC_ASSERT(Map::kNoSlackTracking == 0);
627 this, IsClearWord32<Map::ConstructionCounterBits>(LoadMapBitField3(map)));
628 Node* empty_fixed_array = EmptyFixedArrayConstant();
630 AllocateJSObjectFromMap(map, empty_fixed_array, empty_fixed_array);
635 TF_BUILTIN(ObjectConstructor, ConstructorBuiltinsAssembler) {
636 int const kValueArg = 0;
638 ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
639 CodeStubArguments args(
this, argc);
640 Node* context = Parameter(Descriptor::kContext);
641 Node* new_target = Parameter(Descriptor::kJSNewTarget);
643 VARIABLE(var_result, MachineRepresentation::kTagged);
644 Label if_subclass(
this, Label::kDeferred), if_notsubclass(
this),
646 GotoIf(IsUndefined(new_target), &if_notsubclass);
647 TNode<JSFunction> target = CAST(Parameter(Descriptor::kJSTarget));
648 Branch(WordEqual(new_target, target), &if_notsubclass, &if_subclass);
653 CallBuiltin(Builtins::kFastNewObject, context, target, new_target);
654 var_result.Bind(result);
655 Goto(&return_result);
658 BIND(&if_notsubclass);
660 Label if_newobject(
this, Label::kDeferred), if_toobject(
this);
662 Node* value_index = IntPtrConstant(kValueArg);
663 GotoIf(UintPtrGreaterThanOrEqual(value_index, argc), &if_newobject);
664 Node* value = args.AtIndex(value_index);
665 GotoIf(IsNull(value), &if_newobject);
666 Branch(IsUndefined(value), &if_newobject, &if_toobject);
670 Node* result = EmitCreateEmptyObjectLiteral(context);
671 var_result.Bind(result);
672 Goto(&return_result);
677 Node* result = CallBuiltin(Builtins::kToObject, context, value);
678 var_result.Bind(result);
679 Goto(&return_result);
683 BIND(&return_result);
684 args.PopAndReturn(var_result.value());
688 TF_BUILTIN(NumberConstructor, ConstructorBuiltinsAssembler) {
689 Node* context = Parameter(Descriptor::kContext);
691 ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
692 CodeStubArguments args(
this, argc);
695 VARIABLE(var_n, MachineRepresentation::kTagged, SmiConstant(0));
696 Label if_nloaded(
this, &var_n);
697 GotoIf(WordEqual(argc, IntPtrConstant(0)), &if_nloaded);
703 Node* value = args.AtIndex(0);
704 var_n.Bind(ToNumber(context, value, BigIntHandling::kConvertToNumber));
710 Node* n_value = var_n.value();
711 Node* new_target = Parameter(Descriptor::kJSNewTarget);
712 Label return_n(
this), constructnumber(
this, Label::kDeferred);
713 Branch(IsUndefined(new_target), &return_n, &constructnumber);
716 { args.PopAndReturn(n_value); }
718 BIND(&constructnumber);
728 TNode<JSFunction> target = LoadTargetFromFrame();
730 CallBuiltin(Builtins::kFastNewObject, context, target, new_target);
731 StoreObjectField(result, JSValue::kValueOffset, n_value);
732 args.PopAndReturn(result);
737 TF_BUILTIN(GenericConstructorLazyDeoptContinuation,
738 ConstructorBuiltinsAssembler) {
739 Node* result = Parameter(Descriptor::kResult);
744 TF_BUILTIN(StringConstructor, ConstructorBuiltinsAssembler) {
745 Node* context = Parameter(Descriptor::kContext);
747 ChangeInt32ToIntPtr(Parameter(Descriptor::kJSActualArgumentsCount));
748 CodeStubArguments args(
this, argc);
750 TNode<Object> new_target = CAST(Parameter(Descriptor::kJSNewTarget));
753 VARIABLE(var_s, MachineRepresentation::kTagged, EmptyStringConstant());
754 Label if_sloaded(
this, &var_s);
755 GotoIf(WordEqual(argc, IntPtrConstant(0)), &if_sloaded);
759 Node* value = args.AtIndex(0);
760 Label if_tostring(
this, &var_s);
761 GotoIfNot(IsUndefined(new_target), &if_tostring);
764 GotoIf(TaggedIsSmi(value), &if_tostring);
765 GotoIfNot(IsSymbol(value), &if_tostring);
768 CallRuntime(Runtime::kSymbolDescriptiveString, context, value);
769 args.PopAndReturn(result);
775 var_s.Bind(CallBuiltin(Builtins::kToString, context, value));
782 Node* s_value = var_s.value();
783 Label return_s(
this), constructstring(
this, Label::kDeferred);
784 Branch(IsUndefined(new_target), &return_s, &constructstring);
787 { args.PopAndReturn(s_value); }
789 BIND(&constructstring);
794 TNode<JSFunction> target = LoadTargetFromFrame();
797 CallBuiltin(Builtins::kFastNewObject, context, target, new_target);
798 StoreObjectField(result, JSValue::kValueOffset, s_value);
799 args.PopAndReturn(result);