667
775
// -----------------------------------
669
777
// Enter a construct frame.
670
__ EnterConstructFrame();
672
// Preserve the two incoming parameters on the stack.
673
__ sll(a0, a0, kSmiTagSize); // Tag arguments count.
674
__ MultiPushReversed(a0.bit() | a1.bit());
676
// Use t7 to hold undefined, which is used in several places below.
677
__ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
679
Label rt_call, allocated;
680
// Try to allocate the object without transitioning into C code. If any of the
681
// preconditions is not met, the code bails out to the runtime call.
682
if (FLAG_inline_new) {
683
Label undo_allocation;
779
FrameScope scope(masm, StackFrame::CONSTRUCT);
781
// Preserve the two incoming parameters on the stack.
782
__ sll(a0, a0, kSmiTagSize); // Tag arguments count.
783
__ MultiPushReversed(a0.bit() | a1.bit());
785
// Use t7 to hold undefined, which is used in several places below.
786
__ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
788
Label rt_call, allocated;
789
// Try to allocate the object without transitioning into C code. If any of
790
// the preconditions is not met, the code bails out to the runtime call.
791
if (FLAG_inline_new) {
792
Label undo_allocation;
684
793
#ifdef ENABLE_DEBUGGER_SUPPORT
685
ExternalReference debug_step_in_fp =
686
ExternalReference::debug_step_in_fp_address(isolate);
687
__ li(a2, Operand(debug_step_in_fp));
688
__ lw(a2, MemOperand(a2));
689
__ Branch(&rt_call, ne, a2, Operand(zero_reg));
794
ExternalReference debug_step_in_fp =
795
ExternalReference::debug_step_in_fp_address(isolate);
796
__ li(a2, Operand(debug_step_in_fp));
797
__ lw(a2, MemOperand(a2));
798
__ Branch(&rt_call, ne, a2, Operand(zero_reg));
692
// Load the initial map and verify that it is in fact a map.
693
// a1: constructor function
694
__ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
695
__ And(t0, a2, Operand(kSmiTagMask));
696
__ Branch(&rt_call, eq, t0, Operand(zero_reg));
697
__ GetObjectType(a2, a3, t4);
698
__ Branch(&rt_call, ne, t4, Operand(MAP_TYPE));
700
// Check that the constructor is not constructing a JSFunction (see comments
701
// in Runtime_NewObject in runtime.cc). In which case the initial map's
702
// instance type would be JS_FUNCTION_TYPE.
703
// a1: constructor function
705
__ lbu(a3, FieldMemOperand(a2, Map::kInstanceTypeOffset));
706
__ Branch(&rt_call, eq, a3, Operand(JS_FUNCTION_TYPE));
708
if (count_constructions) {
710
// Decrease generous allocation count.
711
__ lw(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
712
MemOperand constructor_count =
713
FieldMemOperand(a3, SharedFunctionInfo::kConstructionCountOffset);
714
__ lbu(t0, constructor_count);
715
__ Subu(t0, t0, Operand(1));
716
__ sb(t0, constructor_count);
717
__ Branch(&allocate, ne, t0, Operand(zero_reg));
721
__ push(a1); // Constructor.
722
// The call will replace the stub, so the countdown is only done once.
723
__ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
731
// Now allocate the JSObject on the heap.
732
// a1: constructor function
734
__ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset));
735
__ AllocateInNewSpace(a3, t4, t5, t6, &rt_call, SIZE_IN_WORDS);
737
// Allocated the JSObject, now initialize the fields. Map is set to initial
738
// map and properties and elements are set to empty fixed array.
739
// a1: constructor function
742
// t4: JSObject (not tagged)
743
__ LoadRoot(t6, Heap::kEmptyFixedArrayRootIndex);
745
__ sw(a2, MemOperand(t5, JSObject::kMapOffset));
746
__ sw(t6, MemOperand(t5, JSObject::kPropertiesOffset));
747
__ sw(t6, MemOperand(t5, JSObject::kElementsOffset));
748
__ Addu(t5, t5, Operand(3*kPointerSize));
749
ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
750
ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset);
751
ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset);
753
// Fill all the in-object properties with appropriate filler.
754
// a1: constructor function
756
// a3: object size (in words)
757
// t4: JSObject (not tagged)
758
// t5: First in-object property of JSObject (not tagged)
759
__ sll(t0, a3, kPointerSizeLog2);
760
__ addu(t6, t4, t0); // End of object.
761
ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize);
763
if (count_constructions) {
801
// Load the initial map and verify that it is in fact a map.
802
// a1: constructor function
803
__ lw(a2, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset));
804
__ JumpIfSmi(a2, &rt_call);
805
__ GetObjectType(a2, a3, t4);
806
__ Branch(&rt_call, ne, t4, Operand(MAP_TYPE));
808
// Check that the constructor is not constructing a JSFunction (see
809
// comments in Runtime_NewObject in runtime.cc). In which case the
810
// initial map's instance type would be JS_FUNCTION_TYPE.
811
// a1: constructor function
813
__ lbu(a3, FieldMemOperand(a2, Map::kInstanceTypeOffset));
814
__ Branch(&rt_call, eq, a3, Operand(JS_FUNCTION_TYPE));
816
if (count_constructions) {
818
// Decrease generous allocation count.
819
__ lw(a3, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
820
MemOperand constructor_count =
821
FieldMemOperand(a3, SharedFunctionInfo::kConstructionCountOffset);
822
__ lbu(t0, constructor_count);
823
__ Subu(t0, t0, Operand(1));
824
__ sb(t0, constructor_count);
825
__ Branch(&allocate, ne, t0, Operand(zero_reg));
829
__ push(a1); // Constructor.
830
// The call will replace the stub, so the countdown is only done once.
831
__ CallRuntime(Runtime::kFinalizeInstanceSize, 1);
839
// Now allocate the JSObject on the heap.
840
// a1: constructor function
842
__ lbu(a3, FieldMemOperand(a2, Map::kInstanceSizeOffset));
843
__ AllocateInNewSpace(a3, t4, t5, t6, &rt_call, SIZE_IN_WORDS);
845
// Allocated the JSObject, now initialize the fields. Map is set to
846
// initial map and properties and elements are set to empty fixed array.
847
// a1: constructor function
850
// t4: JSObject (not tagged)
851
__ LoadRoot(t6, Heap::kEmptyFixedArrayRootIndex);
853
__ sw(a2, MemOperand(t5, JSObject::kMapOffset));
854
__ sw(t6, MemOperand(t5, JSObject::kPropertiesOffset));
855
__ sw(t6, MemOperand(t5, JSObject::kElementsOffset));
856
__ Addu(t5, t5, Operand(3*kPointerSize));
857
ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
858
ASSERT_EQ(1 * kPointerSize, JSObject::kPropertiesOffset);
859
ASSERT_EQ(2 * kPointerSize, JSObject::kElementsOffset);
861
// Fill all the in-object properties with appropriate filler.
862
// a1: constructor function
864
// a3: object size (in words)
865
// t4: JSObject (not tagged)
866
// t5: First in-object property of JSObject (not tagged)
867
__ sll(t0, a3, kPointerSizeLog2);
868
__ addu(t6, t4, t0); // End of object.
869
ASSERT_EQ(3 * kPointerSize, JSObject::kHeaderSize);
870
__ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
871
if (count_constructions) {
872
__ lw(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset));
873
__ Ext(a0, a0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte,
875
__ sll(t0, a0, kPointerSizeLog2);
877
// a0: offset of first field after pre-allocated fields
878
if (FLAG_debug_code) {
879
__ Assert(le, "Unexpected number of pre-allocated property fields.",
882
__ InitializeFieldsWithFiller(t5, a0, t7);
764
883
// To allow for truncation.
765
884
__ LoadRoot(t7, Heap::kOnePointerFillerMapRootIndex);
767
__ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
771
__ sw(t7, MemOperand(t5, 0));
772
__ addiu(t5, t5, kPointerSize);
774
__ Branch(&loop, Uless, t5, Operand(t6));
777
// Add the object tag to make the JSObject real, so that we can continue and
778
// jump into the continuation code at any time from now on. Any failures
779
// need to undo the allocation, so that the heap is in a consistent state
781
__ Addu(t4, t4, Operand(kHeapObjectTag));
783
// Check if a non-empty properties array is needed. Continue with allocated
784
// object if not fall through to runtime call if it is.
785
// a1: constructor function
787
// t5: start of next object (not tagged)
788
__ lbu(a3, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset));
789
// The field instance sizes contains both pre-allocated property fields and
790
// in-object properties.
791
__ lw(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset));
794
Operand(0x000000FF << Map::kPreAllocatedPropertyFieldsByte * 8));
795
__ srl(t0, t6, Map::kPreAllocatedPropertyFieldsByte * 8);
796
__ Addu(a3, a3, Operand(t0));
797
__ And(t6, a0, Operand(0x000000FF << Map::kInObjectPropertiesByte * 8));
798
__ srl(t0, t6, Map::kInObjectPropertiesByte * 8);
801
// Done if no extra properties are to be allocated.
802
__ Branch(&allocated, eq, a3, Operand(zero_reg));
803
__ Assert(greater_equal, "Property allocation count failed.",
804
a3, Operand(zero_reg));
806
// Scale the number of elements by pointer size and add the header for
807
// FixedArrays to the start of the next object calculation from above.
809
// a3: number of elements in properties array
811
// t5: start of next object
812
__ Addu(a0, a3, Operand(FixedArray::kHeaderSize / kPointerSize));
813
__ AllocateInNewSpace(
819
static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | SIZE_IN_WORDS));
821
// Initialize the FixedArray.
823
// a3: number of elements in properties array (un-tagged)
825
// t5: start of next object
826
__ LoadRoot(t6, Heap::kFixedArrayMapRootIndex);
828
__ sw(t6, MemOperand(a2, JSObject::kMapOffset));
829
__ sll(a0, a3, kSmiTagSize);
830
__ sw(a0, MemOperand(a2, FixedArray::kLengthOffset));
831
__ Addu(a2, a2, Operand(2 * kPointerSize));
833
ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
834
ASSERT_EQ(1 * kPointerSize, FixedArray::kLengthOffset);
836
// Initialize the fields to undefined.
838
// a2: First element of FixedArray (not tagged)
839
// a3: number of elements in properties array
841
// t5: FixedArray (not tagged)
842
__ sll(t3, a3, kPointerSizeLog2);
843
__ addu(t6, a2, t3); // End of object.
844
ASSERT_EQ(2 * kPointerSize, FixedArray::kHeaderSize);
846
if (count_constructions) {
847
__ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
848
} else if (FLAG_debug_code) {
849
__ LoadRoot(t8, Heap::kUndefinedValueRootIndex);
850
__ Assert(eq, "Undefined value not loaded.", t7, Operand(t8));
854
__ sw(t7, MemOperand(a2));
855
__ addiu(a2, a2, kPointerSize);
857
__ Branch(&loop, less, a2, Operand(t6));
860
// Store the initialized FixedArray into the properties field of
862
// a1: constructor function
864
// t5: FixedArray (not tagged)
865
__ Addu(t5, t5, Operand(kHeapObjectTag)); // Add the heap tag.
866
__ sw(t5, FieldMemOperand(t4, JSObject::kPropertiesOffset));
868
// Continue with JSObject being successfully allocated.
869
// a1: constructor function
873
// Undo the setting of the new top so that the heap is verifiable. For
874
// example, the map's unused properties potentially do not match the
875
// allocated objects unused properties.
876
// t4: JSObject (previous new top)
877
__ bind(&undo_allocation);
878
__ UndoAllocationInNewSpace(t4, t5);
882
// Allocate the new receiver object using the runtime call.
883
// a1: constructor function
884
__ push(a1); // Argument for Runtime_NewObject.
885
__ CallRuntime(Runtime::kNewObject, 1);
888
// Receiver for constructor call allocated.
893
// Push the function and the allocated receiver from the stack.
894
// sp[0]: receiver (newly allocated object)
895
// sp[1]: constructor function
896
// sp[2]: number of arguments (smi-tagged)
897
__ lw(a1, MemOperand(sp, kPointerSize));
898
__ MultiPushReversed(a1.bit() | t4.bit());
900
// Reload the number of arguments from the stack.
901
// a1: constructor function
903
// sp[1]: constructor function
905
// sp[3]: constructor function
906
// sp[4]: number of arguments (smi-tagged)
907
__ lw(a3, MemOperand(sp, 4 * kPointerSize));
909
// Setup pointer to last argument.
910
__ Addu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
912
// Setup number of arguments for function call below.
913
__ srl(a0, a3, kSmiTagSize);
915
// Copy arguments and receiver to the expression stack.
916
// a0: number of arguments
917
// a1: constructor function
918
// a2: address of last argument (caller sp)
919
// a3: number of arguments (smi-tagged)
921
// sp[1]: constructor function
923
// sp[3]: constructor function
924
// sp[4]: number of arguments (smi-tagged)
928
__ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
929
__ Addu(t0, a2, Operand(t0));
930
__ lw(t1, MemOperand(t0));
933
__ Addu(a3, a3, Operand(-2));
934
__ Branch(&loop, greater_equal, a3, Operand(zero_reg));
936
// Call the function.
937
// a0: number of arguments
938
// a1: constructor function
939
if (is_api_function) {
940
__ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
942
masm->isolate()->builtins()->HandleApiCallConstruct();
943
ParameterCount expected(0);
944
__ InvokeCode(code, expected, expected,
945
RelocInfo::CODE_TARGET, CALL_FUNCTION, CALL_AS_METHOD);
947
ParameterCount actual(a0);
948
__ InvokeFunction(a1, actual, CALL_FUNCTION,
949
NullCallWrapper(), CALL_AS_METHOD);
952
// Pop the function from the stack.
954
// sp[0]: constructor function
956
// sp[3]: constructor function
957
// sp[4]: number of arguments (smi-tagged)
960
// Restore context from the frame.
961
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
963
// If the result is an object (in the ECMA sense), we should get rid
964
// of the receiver and use the result; see ECMA-262 section 13.2.2-7
966
Label use_receiver, exit;
968
// If the result is a smi, it is *not* an object in the ECMA sense.
970
// sp[0]: receiver (newly allocated object)
971
// sp[1]: constructor function
972
// sp[2]: number of arguments (smi-tagged)
973
__ And(t0, v0, Operand(kSmiTagMask));
974
__ Branch(&use_receiver, eq, t0, Operand(zero_reg));
976
// If the type of the result (stored in its map) is less than
977
// FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
978
__ GetObjectType(v0, a3, a3);
979
__ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
981
// Throw away the result of the constructor invocation and use the
982
// on-stack receiver as the result.
983
__ bind(&use_receiver);
984
__ lw(v0, MemOperand(sp));
986
// Remove receiver from the stack, remove caller arguments, and
990
// sp[0]: receiver (newly allocated object)
991
// sp[1]: constructor function
992
// sp[2]: number of arguments (smi-tagged)
993
__ lw(a1, MemOperand(sp, 2 * kPointerSize));
994
__ LeaveConstructFrame();
886
__ InitializeFieldsWithFiller(t5, t6, t7);
888
// Add the object tag to make the JSObject real, so that we can continue
889
// and jump into the continuation code at any time from now on. Any
890
// failures need to undo the allocation, so that the heap is in a
891
// consistent state and verifiable.
892
__ Addu(t4, t4, Operand(kHeapObjectTag));
894
// Check if a non-empty properties array is needed. Continue with
895
// allocated object if not fall through to runtime call if it is.
896
// a1: constructor function
898
// t5: start of next object (not tagged)
899
__ lbu(a3, FieldMemOperand(a2, Map::kUnusedPropertyFieldsOffset));
900
// The field instance sizes contains both pre-allocated property fields
901
// and in-object properties.
902
__ lw(a0, FieldMemOperand(a2, Map::kInstanceSizesOffset));
903
__ Ext(t6, a0, Map::kPreAllocatedPropertyFieldsByte * kBitsPerByte,
905
__ Addu(a3, a3, Operand(t6));
906
__ Ext(t6, a0, Map::kInObjectPropertiesByte * kBitsPerByte,
910
// Done if no extra properties are to be allocated.
911
__ Branch(&allocated, eq, a3, Operand(zero_reg));
912
__ Assert(greater_equal, "Property allocation count failed.",
913
a3, Operand(zero_reg));
915
// Scale the number of elements by pointer size and add the header for
916
// FixedArrays to the start of the next object calculation from above.
918
// a3: number of elements in properties array
920
// t5: start of next object
921
__ Addu(a0, a3, Operand(FixedArray::kHeaderSize / kPointerSize));
922
__ AllocateInNewSpace(
928
static_cast<AllocationFlags>(RESULT_CONTAINS_TOP | SIZE_IN_WORDS));
930
// Initialize the FixedArray.
932
// a3: number of elements in properties array (untagged)
934
// t5: start of next object
935
__ LoadRoot(t6, Heap::kFixedArrayMapRootIndex);
937
__ sw(t6, MemOperand(a2, JSObject::kMapOffset));
938
__ sll(a0, a3, kSmiTagSize);
939
__ sw(a0, MemOperand(a2, FixedArray::kLengthOffset));
940
__ Addu(a2, a2, Operand(2 * kPointerSize));
942
ASSERT_EQ(0 * kPointerSize, JSObject::kMapOffset);
943
ASSERT_EQ(1 * kPointerSize, FixedArray::kLengthOffset);
945
// Initialize the fields to undefined.
947
// a2: First element of FixedArray (not tagged)
948
// a3: number of elements in properties array
950
// t5: FixedArray (not tagged)
951
__ sll(t3, a3, kPointerSizeLog2);
952
__ addu(t6, a2, t3); // End of object.
953
ASSERT_EQ(2 * kPointerSize, FixedArray::kHeaderSize);
955
if (count_constructions) {
956
__ LoadRoot(t7, Heap::kUndefinedValueRootIndex);
957
} else if (FLAG_debug_code) {
958
__ LoadRoot(t8, Heap::kUndefinedValueRootIndex);
959
__ Assert(eq, "Undefined value not loaded.", t7, Operand(t8));
963
__ sw(t7, MemOperand(a2));
964
__ addiu(a2, a2, kPointerSize);
966
__ Branch(&loop, less, a2, Operand(t6));
969
// Store the initialized FixedArray into the properties field of
971
// a1: constructor function
973
// t5: FixedArray (not tagged)
974
__ Addu(t5, t5, Operand(kHeapObjectTag)); // Add the heap tag.
975
__ sw(t5, FieldMemOperand(t4, JSObject::kPropertiesOffset));
977
// Continue with JSObject being successfully allocated.
978
// a1: constructor function
982
// Undo the setting of the new top so that the heap is verifiable. For
983
// example, the map's unused properties potentially do not match the
984
// allocated objects unused properties.
985
// t4: JSObject (previous new top)
986
__ bind(&undo_allocation);
987
__ UndoAllocationInNewSpace(t4, t5);
991
// Allocate the new receiver object using the runtime call.
992
// a1: constructor function
993
__ push(a1); // Argument for Runtime_NewObject.
994
__ CallRuntime(Runtime::kNewObject, 1);
997
// Receiver for constructor call allocated.
1003
// Reload the number of arguments from the stack.
1006
// sp[2]: constructor function
1007
// sp[3]: number of arguments (smi-tagged)
1008
__ lw(a1, MemOperand(sp, 2 * kPointerSize));
1009
__ lw(a3, MemOperand(sp, 3 * kPointerSize));
1011
// Set up pointer to last argument.
1012
__ Addu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset));
1014
// Set up number of arguments for function call below.
1015
__ srl(a0, a3, kSmiTagSize);
1017
// Copy arguments and receiver to the expression stack.
1018
// a0: number of arguments
1019
// a1: constructor function
1020
// a2: address of last argument (caller sp)
1021
// a3: number of arguments (smi-tagged)
1024
// sp[2]: constructor function
1025
// sp[3]: number of arguments (smi-tagged)
1029
__ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
1030
__ Addu(t0, a2, Operand(t0));
1031
__ lw(t1, MemOperand(t0));
1034
__ Addu(a3, a3, Operand(-2));
1035
__ Branch(&loop, greater_equal, a3, Operand(zero_reg));
1037
// Call the function.
1038
// a0: number of arguments
1039
// a1: constructor function
1040
if (is_api_function) {
1041
__ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
1043
masm->isolate()->builtins()->HandleApiCallConstruct();
1044
ParameterCount expected(0);
1045
__ InvokeCode(code, expected, expected,
1046
RelocInfo::CODE_TARGET, CALL_FUNCTION, CALL_AS_METHOD);
1048
ParameterCount actual(a0);
1049
__ InvokeFunction(a1, actual, CALL_FUNCTION,
1050
NullCallWrapper(), CALL_AS_METHOD);
1053
// Store offset of return address for deoptimizer.
1054
if (!is_api_function && !count_constructions) {
1055
masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
1058
// Restore context from the frame.
1059
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
1061
// If the result is an object (in the ECMA sense), we should get rid
1062
// of the receiver and use the result; see ECMA-262 section 13.2.2-7
1064
Label use_receiver, exit;
1066
// If the result is a smi, it is *not* an object in the ECMA sense.
1068
// sp[0]: receiver (newly allocated object)
1069
// sp[1]: constructor function
1070
// sp[2]: number of arguments (smi-tagged)
1071
__ JumpIfSmi(v0, &use_receiver);
1073
// If the type of the result (stored in its map) is less than
1074
// FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
1075
__ GetObjectType(v0, a3, a3);
1076
__ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
1078
// Throw away the result of the constructor invocation and use the
1079
// on-stack receiver as the result.
1080
__ bind(&use_receiver);
1081
__ lw(v0, MemOperand(sp));
1083
// Remove receiver from the stack, remove caller arguments, and
1087
// sp[0]: receiver (newly allocated object)
1088
// sp[1]: constructor function
1089
// sp[2]: number of arguments (smi-tagged)
1090
__ lw(a1, MemOperand(sp, 2 * kPointerSize));
1092
// Leave construct frame.
995
1095
__ sll(t0, a1, kPointerSizeLog2 - 1);
996
1096
__ Addu(sp, sp, t0);
997
1097
__ Addu(sp, sp, kPointerSize);
1350
1541
const int kRecvOffset = 3 * kPointerSize;
1351
1542
const int kFunctionOffset = 4 * kPointerSize;
1353
__ EnterInternalFrame();
1355
__ lw(a0, MemOperand(fp, kFunctionOffset)); // Get the function.
1357
__ lw(a0, MemOperand(fp, kArgsOffset)); // Get the args array.
1359
// Returns (in v0) number of arguments to copy to stack as Smi.
1360
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
1362
// Check the stack for overflow. We are not trying need to catch
1363
// interruptions (e.g. debug break and preemption) here, so the "real stack
1364
// limit" is checked.
1366
__ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
1367
// Make a2 the space we have left. The stack might already be overflowed
1368
// here which will cause a2 to become negative.
1369
__ subu(a2, sp, a2);
1370
// Check if the arguments will overflow the stack.
1371
__ sll(t0, v0, kPointerSizeLog2 - kSmiTagSize);
1372
__ Branch(&okay, gt, a2, Operand(t0)); // Signed comparison.
1374
// Out of stack space.
1375
__ lw(a1, MemOperand(fp, kFunctionOffset));
1378
__ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
1379
// End of stack check.
1381
// Push current limit and index.
1383
__ push(v0); // Limit.
1384
__ mov(a1, zero_reg); // Initial index.
1387
// Change context eagerly to get the right global object if necessary.
1388
__ lw(a0, MemOperand(fp, kFunctionOffset));
1389
__ lw(cp, FieldMemOperand(a0, JSFunction::kContextOffset));
1390
// Load the shared function info while the function is still in a0.
1391
__ lw(a1, FieldMemOperand(a0, JSFunction::kSharedFunctionInfoOffset));
1393
// Compute the receiver.
1394
Label call_to_object, use_global_receiver, push_receiver;
1395
__ lw(a0, MemOperand(fp, kRecvOffset));
1397
// Do not transform the receiver for strict mode functions.
1398
__ lw(a2, FieldMemOperand(a1, SharedFunctionInfo::kCompilerHintsOffset));
1399
__ And(t0, a2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
1401
__ Branch(&push_receiver, ne, t0, Operand(zero_reg));
1403
// Do not transform the receiver for native (Compilerhints already in a2).
1404
__ And(t0, a2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
1405
__ Branch(&push_receiver, ne, t0, Operand(zero_reg));
1407
// Compute the receiver in non-strict mode.
1408
__ And(t0, a0, Operand(kSmiTagMask));
1409
__ Branch(&call_to_object, eq, t0, Operand(zero_reg));
1410
__ LoadRoot(a1, Heap::kNullValueRootIndex);
1411
__ Branch(&use_global_receiver, eq, a0, Operand(a1));
1412
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
1413
__ Branch(&use_global_receiver, eq, a0, Operand(a2));
1415
// Check if the receiver is already a JavaScript object.
1417
STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
1418
__ GetObjectType(a0, a1, a1);
1419
__ Branch(&push_receiver, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
1421
// Convert the receiver to a regular object.
1423
__ bind(&call_to_object);
1425
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
1426
__ mov(a0, v0); // Put object in a0 to match other paths to push_receiver.
1427
__ Branch(&push_receiver);
1429
// Use the current global receiver object as the receiver.
1430
__ bind(&use_global_receiver);
1431
const int kGlobalOffset =
1432
Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
1433
__ lw(a0, FieldMemOperand(cp, kGlobalOffset));
1434
__ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalContextOffset));
1435
__ lw(a0, FieldMemOperand(a0, kGlobalOffset));
1436
__ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
1438
// Push the receiver.
1440
__ bind(&push_receiver);
1443
// Copy all arguments from the array to the stack.
1445
__ lw(a0, MemOperand(fp, kIndexOffset));
1448
// Load the current argument from the arguments array and push it to the
1450
// a0: current argument index
1452
__ lw(a1, MemOperand(fp, kArgsOffset));
1456
// Call the runtime to access the property in the arguments array.
1457
__ CallRuntime(Runtime::kGetProperty, 2);
1460
// Use inline caching to access the arguments.
1461
__ lw(a0, MemOperand(fp, kIndexOffset));
1462
__ Addu(a0, a0, Operand(1 << kSmiTagSize));
1463
__ sw(a0, MemOperand(fp, kIndexOffset));
1465
// Test if the copy loop has finished copying all the elements from the
1466
// arguments object.
1468
__ lw(a1, MemOperand(fp, kLimitOffset));
1469
__ Branch(&loop, ne, a0, Operand(a1));
1470
// Invoke the function.
1471
ParameterCount actual(a0);
1472
__ sra(a0, a0, kSmiTagSize);
1473
__ lw(a1, MemOperand(fp, kFunctionOffset));
1474
__ InvokeFunction(a1, actual, CALL_FUNCTION,
1475
NullCallWrapper(), CALL_AS_METHOD);
1477
// Tear down the internal frame and remove function, receiver and args.
1478
__ LeaveInternalFrame();
1479
__ Addu(sp, sp, Operand(3 * kPointerSize));
1545
FrameScope frame_scope(masm, StackFrame::INTERNAL);
1546
__ lw(a0, MemOperand(fp, kFunctionOffset)); // Get the function.
1548
__ lw(a0, MemOperand(fp, kArgsOffset)); // Get the args array.
1550
// Returns (in v0) number of arguments to copy to stack as Smi.
1551
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
1553
// Check the stack for overflow. We are not trying to catch
1554
// interruptions (e.g. debug break and preemption) here, so the "real stack
1555
// limit" is checked.
1557
__ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
1558
// Make a2 the space we have left. The stack might already be overflowed
1559
// here which will cause a2 to become negative.
1560
__ subu(a2, sp, a2);
1561
// Check if the arguments will overflow the stack.
1562
__ sll(t3, v0, kPointerSizeLog2 - kSmiTagSize);
1563
__ Branch(&okay, gt, a2, Operand(t3)); // Signed comparison.
1565
// Out of stack space.
1566
__ lw(a1, MemOperand(fp, kFunctionOffset));
1569
__ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
1570
// End of stack check.
1572
// Push current limit and index.
1574
__ push(v0); // Limit.
1575
__ mov(a1, zero_reg); // Initial index.
1578
// Get the receiver.
1579
__ lw(a0, MemOperand(fp, kRecvOffset));
1581
// Check that the function is a JS function (otherwise it must be a proxy).
1582
Label push_receiver;
1583
__ lw(a1, MemOperand(fp, kFunctionOffset));
1584
__ GetObjectType(a1, a2, a2);
1585
__ Branch(&push_receiver, ne, a2, Operand(JS_FUNCTION_TYPE));
1587
// Change context eagerly to get the right global object if necessary.
1588
__ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
1589
// Load the shared function info while the function is still in a1.
1590
__ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
1592
// Compute the receiver.
1593
// Do not transform the receiver for strict mode functions.
1594
Label call_to_object, use_global_receiver;
1595
__ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset));
1596
__ And(t3, a2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
1598
__ Branch(&push_receiver, ne, t3, Operand(zero_reg));
1600
// Do not transform the receiver for native (Compilerhints already in a2).
1601
__ And(t3, a2, Operand(1 << (SharedFunctionInfo::kNative + kSmiTagSize)));
1602
__ Branch(&push_receiver, ne, t3, Operand(zero_reg));
1604
// Compute the receiver in non-strict mode.
1605
__ JumpIfSmi(a0, &call_to_object);
1606
__ LoadRoot(a1, Heap::kNullValueRootIndex);
1607
__ Branch(&use_global_receiver, eq, a0, Operand(a1));
1608
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
1609
__ Branch(&use_global_receiver, eq, a0, Operand(a2));
1611
// Check if the receiver is already a JavaScript object.
1613
STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
1614
__ GetObjectType(a0, a1, a1);
1615
__ Branch(&push_receiver, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
1617
// Convert the receiver to a regular object.
1619
__ bind(&call_to_object);
1621
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
1622
__ mov(a0, v0); // Put object in a0 to match other paths to push_receiver.
1623
__ Branch(&push_receiver);
1625
// Use the current global receiver object as the receiver.
1626
__ bind(&use_global_receiver);
1627
const int kGlobalOffset =
1628
Context::kHeaderSize + Context::GLOBAL_OBJECT_INDEX * kPointerSize;
1629
__ lw(a0, FieldMemOperand(cp, kGlobalOffset));
1630
__ lw(a0, FieldMemOperand(a0, GlobalObject::kNativeContextOffset));
1631
__ lw(a0, FieldMemOperand(a0, kGlobalOffset));
1632
__ lw(a0, FieldMemOperand(a0, GlobalObject::kGlobalReceiverOffset));
1634
// Push the receiver.
1636
__ bind(&push_receiver);
1639
// Copy all arguments from the array to the stack.
1641
__ lw(a0, MemOperand(fp, kIndexOffset));
1644
// Load the current argument from the arguments array and push it to the
1646
// a0: current argument index
1648
__ lw(a1, MemOperand(fp, kArgsOffset));
1652
// Call the runtime to access the property in the arguments array.
1653
__ CallRuntime(Runtime::kGetProperty, 2);
1656
// Use inline caching to access the arguments.
1657
__ lw(a0, MemOperand(fp, kIndexOffset));
1658
__ Addu(a0, a0, Operand(1 << kSmiTagSize));
1659
__ sw(a0, MemOperand(fp, kIndexOffset));
1661
// Test if the copy loop has finished copying all the elements from the
1662
// arguments object.
1664
__ lw(a1, MemOperand(fp, kLimitOffset));
1665
__ Branch(&loop, ne, a0, Operand(a1));
1667
// Invoke the function.
1669
ParameterCount actual(a0);
1670
__ sra(a0, a0, kSmiTagSize);
1671
__ lw(a1, MemOperand(fp, kFunctionOffset));
1672
__ GetObjectType(a1, a2, a2);
1673
__ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE));
1675
__ InvokeFunction(a1, actual, CALL_FUNCTION,
1676
NullCallWrapper(), CALL_AS_METHOD);
1678
frame_scope.GenerateLeaveFrame();
1679
__ Ret(USE_DELAY_SLOT);
1680
__ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot.
1682
// Invoke the function proxy.
1683
__ bind(&call_proxy);
1684
__ push(a1); // Add function proxy as last argument.
1685
__ Addu(a0, a0, Operand(1));
1686
__ li(a2, Operand(0, RelocInfo::NONE));
1687
__ SetCallKind(t1, CALL_AS_METHOD);
1688
__ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
1689
__ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
1690
RelocInfo::CODE_TARGET);
1691
// Tear down the internal frame and remove function, receiver and args.
1694
__ Ret(USE_DELAY_SLOT);
1695
__ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot.