Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(637)

Side by Side Diff: src/ia32/builtins-ia32.cc

Issue 1533803002: Revert of [es6] Correct Function.prototype.apply, Reflect.construct and Reflect.apply. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/contexts.h ('k') | src/js/runtime.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/codegen.h" 8 #include "src/codegen.h"
9 #include "src/deoptimizer.h" 9 #include "src/deoptimizer.h"
10 #include "src/full-codegen/full-codegen.h" 10 #include "src/full-codegen/full-codegen.h"
(...skipping 939 matching lines...) Expand 10 before | Expand all | Expand 10 after
950 __ j(not_sign, &loop); // While non-negative (to copy return address). 950 __ j(not_sign, &loop); // While non-negative (to copy return address).
951 __ pop(ebx); // Discard copy of return address. 951 __ pop(ebx); // Discard copy of return address.
952 __ dec(eax); // One fewer argument (first argument is new receiver). 952 __ dec(eax); // One fewer argument (first argument is new receiver).
953 } 953 }
954 954
955 // 4. Call the callable. 955 // 4. Call the callable.
956 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); 956 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
957 } 957 }
958 958
959 959
960 static void Generate_PushAppliedArguments(MacroAssembler* masm,
961 const int vectorOffset,
962 const int argumentsOffset,
963 const int indexOffset,
964 const int limitOffset) {
965 // Copy all arguments from the array to the stack.
966 Label entry, loop;
967 Register receiver = LoadDescriptor::ReceiverRegister();
968 Register key = LoadDescriptor::NameRegister();
969 Register slot = LoadDescriptor::SlotRegister();
970 Register vector = LoadWithVectorDescriptor::VectorRegister();
971 __ mov(key, Operand(ebp, indexOffset));
972 __ jmp(&entry);
973 __ bind(&loop);
974 __ mov(receiver, Operand(ebp, argumentsOffset)); // load arguments
975
976 // Use inline caching to speed up access to arguments.
977 int slot_index = TypeFeedbackVector::PushAppliedArgumentsIndex();
978 __ mov(slot, Immediate(Smi::FromInt(slot_index)));
979 __ mov(vector, Operand(ebp, vectorOffset));
980 Handle<Code> ic =
981 KeyedLoadICStub(masm->isolate(), LoadICState(kNoExtraICState)).GetCode();
982 __ call(ic, RelocInfo::CODE_TARGET);
983 // It is important that we do not have a test instruction after the
984 // call. A test instruction after the call is used to indicate that
985 // we have generated an inline version of the keyed load. In this
986 // case, we know that we are not generating a test instruction next.
987
988 // Push the nth argument.
989 __ push(eax);
990
991 // Update the index on the stack and in register key.
992 __ mov(key, Operand(ebp, indexOffset));
993 __ add(key, Immediate(1 << kSmiTagSize));
994 __ mov(Operand(ebp, indexOffset), key);
995
996 __ bind(&entry);
997 __ cmp(key, Operand(ebp, limitOffset));
998 __ j(not_equal, &loop);
999
1000 // On exit, the pushed arguments count is in eax, untagged
1001 __ Move(eax, key);
1002 __ SmiUntag(eax);
1003 }
1004
1005
1006 // Used by FunctionApply and ReflectApply
1007 static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) {
1008 const int kFormalParameters = targetIsArgument ? 3 : 2;
1009 const int kStackSize = kFormalParameters + 1;
1010
1011 // Stack at entry:
1012 // esp : return address
1013 // esp[4] : arguments
1014 // esp[8] : receiver ("this")
1015 // esp[12] : function
1016 {
1017 FrameScope frame_scope(masm, StackFrame::INTERNAL);
1018 // Stack frame:
1019 // ebp : Old base pointer
1020 // ebp[4] : return address
1021 // ebp[8] : function arguments
1022 // ebp[12] : receiver
1023 // ebp[16] : function
1024 static const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize;
1025 static const int kReceiverOffset = kArgumentsOffset + kPointerSize;
1026 static const int kFunctionOffset = kReceiverOffset + kPointerSize;
1027 static const int kVectorOffset =
1028 InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
1029
1030 // Push the vector.
1031 __ mov(edi, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
1032 __ mov(edi, FieldOperand(edi, SharedFunctionInfo::kFeedbackVectorOffset));
1033 __ push(edi);
1034
1035 __ push(Operand(ebp, kFunctionOffset)); // push this
1036 __ push(Operand(ebp, kArgumentsOffset)); // push arguments
1037 if (targetIsArgument) {
1038 __ InvokeBuiltin(Context::REFLECT_APPLY_PREPARE_BUILTIN_INDEX,
1039 CALL_FUNCTION);
1040 } else {
1041 __ InvokeBuiltin(Context::APPLY_PREPARE_BUILTIN_INDEX, CALL_FUNCTION);
1042 }
1043
1044 Generate_CheckStackOverflow(masm, kEaxIsSmiTagged);
1045
1046 // Push current index and limit.
1047 const int kLimitOffset = kVectorOffset - 1 * kPointerSize;
1048 const int kIndexOffset = kLimitOffset - 1 * kPointerSize;
1049 __ Push(eax); // limit
1050 __ Push(Immediate(0)); // index
1051 __ Push(Operand(ebp, kReceiverOffset)); // receiver
1052
1053 // Loop over the arguments array, pushing each value to the stack
1054 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
1055 kIndexOffset, kLimitOffset);
1056
1057 // Call the callable.
1058 // TODO(bmeurer): This should be a tail call according to ES6.
1059 __ mov(edi, Operand(ebp, kFunctionOffset));
1060 __ Call(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1061
1062 // Leave internal frame.
1063 }
1064 __ ret(kStackSize * kPointerSize); // remove this, receiver, and arguments
1065 }
1066
1067
1068 // Used by ReflectConstruct
1069 static void Generate_ConstructHelper(MacroAssembler* masm) {
1070 const int kFormalParameters = 3;
1071 const int kStackSize = kFormalParameters + 1;
1072
1073 // Stack at entry:
1074 // esp : return address
1075 // esp[4] : new target
1076 // esp[8] : arguments
1077 // esp[16] : constructor
1078 {
1079 FrameScope frame_scope(masm, StackFrame::INTERNAL);
1080 // Stack frame:
1081 // ebp : Old base pointer
1082 // ebp[4] : return address
1083 // ebp[8] : new target
1084 // ebp[12] : arguments
1085 // ebp[16] : constructor
1086 static const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize;
1087 static const int kArgumentsOffset = kNewTargetOffset + kPointerSize;
1088 static const int kFunctionOffset = kArgumentsOffset + kPointerSize;
1089 static const int kVectorOffset =
1090 InternalFrameConstants::kCodeOffset - 1 * kPointerSize;
1091
1092 // Push the vector.
1093 __ mov(edi, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
1094 __ mov(edi, FieldOperand(edi, SharedFunctionInfo::kFeedbackVectorOffset));
1095 __ push(edi);
1096
1097 // If newTarget is not supplied, set it to constructor
1098 Label validate_arguments;
1099 __ mov(eax, Operand(ebp, kNewTargetOffset));
1100 __ CompareRoot(eax, Heap::kUndefinedValueRootIndex);
1101 __ j(not_equal, &validate_arguments, Label::kNear);
1102 __ mov(eax, Operand(ebp, kFunctionOffset));
1103 __ mov(Operand(ebp, kNewTargetOffset), eax);
1104
1105 // Validate arguments
1106 __ bind(&validate_arguments);
1107 __ push(Operand(ebp, kFunctionOffset));
1108 __ push(Operand(ebp, kArgumentsOffset));
1109 __ push(Operand(ebp, kNewTargetOffset));
1110 __ InvokeBuiltin(Context::REFLECT_CONSTRUCT_PREPARE_BUILTIN_INDEX,
1111 CALL_FUNCTION);
1112
1113 Generate_CheckStackOverflow(masm, kEaxIsSmiTagged);
1114
1115 // Push current index and limit.
1116 const int kLimitOffset = kVectorOffset - 1 * kPointerSize;
1117 const int kIndexOffset = kLimitOffset - 1 * kPointerSize;
1118 __ Push(eax); // limit
1119 __ push(Immediate(0)); // index
1120 // Push the constructor function as callee.
1121 __ push(Operand(ebp, kFunctionOffset));
1122
1123 // Loop over the arguments array, pushing each value to the stack
1124 Generate_PushAppliedArguments(masm, kVectorOffset, kArgumentsOffset,
1125 kIndexOffset, kLimitOffset);
1126
1127 // Use undefined feedback vector
1128 __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex);
1129 __ mov(edi, Operand(ebp, kFunctionOffset));
1130 __ mov(edx, Operand(ebp, kNewTargetOffset));
1131
1132 // Call the function.
1133 __ Call(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1134
1135 // Leave internal frame.
1136 }
1137 // remove this, target, arguments, and newTarget
1138 __ ret(kStackSize * kPointerSize);
1139 }
1140
1141
960 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { 1142 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
961 // ----------- S t a t e ------------- 1143 Generate_ApplyHelper(masm, false);
962 // -- eax : argc
963 // -- esp[0] : return address
964 // -- esp[4] : argArray
965 // -- esp[8] : thisArg
966 // -- esp[12] : receiver
967 // -----------------------------------
968
969 // 1. Load receiver into edi, argArray into eax (if present), remove all
970 // arguments from the stack (including the receiver), and push thisArg (if
971 // present) instead.
972 {
973 Label no_arg_array, no_this_arg;
974 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
975 __ mov(ebx, edx);
976 __ mov(edi, Operand(esp, eax, times_pointer_size, kPointerSize));
977 __ test(eax, eax);
978 __ j(zero, &no_this_arg, Label::kNear);
979 {
980 __ mov(edx, Operand(esp, eax, times_pointer_size, 0));
981 __ cmp(eax, Immediate(1));
982 __ j(equal, &no_arg_array, Label::kNear);
983 __ mov(ebx, Operand(esp, eax, times_pointer_size, -kPointerSize));
984 __ bind(&no_arg_array);
985 }
986 __ bind(&no_this_arg);
987 __ PopReturnAddressTo(ecx);
988 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
989 __ Push(edx);
990 __ PushReturnAddressFrom(ecx);
991 __ Move(eax, ebx);
992 }
993
994 // ----------- S t a t e -------------
995 // -- eax : argArray
996 // -- edi : receiver
997 // -- esp[0] : return address
998 // -- esp[4] : thisArg
999 // -----------------------------------
1000
1001 // 2. Make sure the receiver is actually callable.
1002 Label receiver_not_callable;
1003 __ JumpIfSmi(edi, &receiver_not_callable, Label::kNear);
1004 __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
1005 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable);
1006 __ j(zero, &receiver_not_callable, Label::kNear);
1007
1008 // 3. Tail call with no arguments if argArray is null or undefined.
1009 Label no_arguments;
1010 __ JumpIfRoot(eax, Heap::kNullValueRootIndex, &no_arguments, Label::kNear);
1011 __ JumpIfRoot(eax, Heap::kUndefinedValueRootIndex, &no_arguments,
1012 Label::kNear);
1013
1014 // 4a. Apply the receiver to the given argArray (passing undefined for
1015 // new.target).
1016 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
1017 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1018
1019 // 4b. The argArray is either null or undefined, so we tail call without any
1020 // arguments to the receiver.
1021 __ bind(&no_arguments);
1022 {
1023 __ Set(eax, 0);
1024 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1025 }
1026
1027 // 4c. The receiver is not callable, throw an appropriate TypeError.
1028 __ bind(&receiver_not_callable);
1029 {
1030 __ mov(Operand(esp, kPointerSize), edi);
1031 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1, 1);
1032 }
1033 } 1144 }
1034 1145
1035 1146
1036 void Builtins::Generate_ReflectApply(MacroAssembler* masm) { 1147 void Builtins::Generate_ReflectApply(MacroAssembler* masm) {
1037 // ----------- S t a t e ------------- 1148 Generate_ApplyHelper(masm, true);
1038 // -- eax : argc
1039 // -- esp[0] : return address
1040 // -- esp[4] : argumentsList
1041 // -- esp[8] : thisArgument
1042 // -- esp[12] : target
1043 // -- esp[16] : receiver
1044 // -----------------------------------
1045
1046 // 1. Load target into edi (if present), argumentsList into eax (if present),
1047 // remove all arguments from the stack (including the receiver), and push
1048 // thisArgument (if present) instead.
1049 {
1050 Label done;
1051 __ LoadRoot(edi, Heap::kUndefinedValueRootIndex);
1052 __ mov(edx, edi);
1053 __ mov(ebx, edi);
1054 __ cmp(eax, Immediate(1));
1055 __ j(below, &done, Label::kNear);
1056 __ mov(edi, Operand(esp, eax, times_pointer_size, -0 * kPointerSize));
1057 __ j(equal, &done, Label::kNear);
1058 __ mov(edx, Operand(esp, eax, times_pointer_size, -1 * kPointerSize));
1059 __ cmp(eax, Immediate(3));
1060 __ j(below, &done, Label::kNear);
1061 __ mov(ebx, Operand(esp, eax, times_pointer_size, -2 * kPointerSize));
1062 __ bind(&done);
1063 __ PopReturnAddressTo(ecx);
1064 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1065 __ Push(edx);
1066 __ PushReturnAddressFrom(ecx);
1067 __ Move(eax, ebx);
1068 }
1069
1070 // ----------- S t a t e -------------
1071 // -- eax : argumentsList
1072 // -- edi : target
1073 // -- esp[0] : return address
1074 // -- esp[4] : thisArgument
1075 // -----------------------------------
1076
1077 // 2. Make sure the target is actually callable.
1078 Label target_not_callable;
1079 __ JumpIfSmi(edi, &target_not_callable, Label::kNear);
1080 __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
1081 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsCallable);
1082 __ j(zero, &target_not_callable, Label::kNear);
1083
1084 // 3a. Apply the target to the given argumentsList (passing undefined for
1085 // new.target).
1086 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex);
1087 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1088
1089 // 3b. The target is not callable, throw an appropriate TypeError.
1090 __ bind(&target_not_callable);
1091 {
1092 __ mov(Operand(esp, kPointerSize), edi);
1093 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1, 1);
1094 }
1095 } 1149 }
1096 1150
1097 1151
1098 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { 1152 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) {
1099 // ----------- S t a t e ------------- 1153 Generate_ConstructHelper(masm);
1100 // -- eax : argc 1154 }
1101 // -- esp[0] : return address 1155
1102 // -- esp[4] : new.target (optional) 1156
1103 // -- esp[8] : argumentsList
1104 // -- esp[12] : target
1105 // -- esp[16] : receiver
1106 // -----------------------------------
1107
1108 // 1. Load target into edi (if present), argumentsList into eax (if present),
1109 // new.target into edx (if present, otherwise use target), remove all
1110 // arguments from the stack (including the receiver), and push thisArgument
1111 // (if present) instead.
1112 {
1113 Label done;
1114 __ LoadRoot(edi, Heap::kUndefinedValueRootIndex);
1115 __ mov(edx, edi);
1116 __ mov(ebx, edi);
1117 __ cmp(eax, Immediate(1));
1118 __ j(below, &done, Label::kNear);
1119 __ mov(edi, Operand(esp, eax, times_pointer_size, -0 * kPointerSize));
1120 __ mov(edx, edi);
1121 __ j(equal, &done, Label::kNear);
1122 __ mov(ebx, Operand(esp, eax, times_pointer_size, -1 * kPointerSize));
1123 __ cmp(eax, Immediate(3));
1124 __ j(below, &done, Label::kNear);
1125 __ mov(edx, Operand(esp, eax, times_pointer_size, -2 * kPointerSize));
1126 __ bind(&done);
1127 __ PopReturnAddressTo(ecx);
1128 __ lea(esp, Operand(esp, eax, times_pointer_size, kPointerSize));
1129 __ PushRoot(Heap::kUndefinedValueRootIndex);
1130 __ PushReturnAddressFrom(ecx);
1131 __ Move(eax, ebx);
1132 }
1133
1134 // ----------- S t a t e -------------
1135 // -- eax : argumentsList
1136 // -- edx : new.target
1137 // -- edi : target
1138 // -- esp[0] : return address
1139 // -- esp[4] : receiver (undefined)
1140 // -----------------------------------
1141
1142 // 2. Make sure the target is actually a constructor.
1143 Label target_not_constructor;
1144 __ JumpIfSmi(edi, &target_not_constructor, Label::kNear);
1145 __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));
1146 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor);
1147 __ j(zero, &target_not_constructor, Label::kNear);
1148
1149 // 3. Make sure the target is actually a constructor.
1150 Label new_target_not_constructor;
1151 __ JumpIfSmi(edx, &new_target_not_constructor, Label::kNear);
1152 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
1153 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor);
1154 __ j(zero, &new_target_not_constructor, Label::kNear);
1155
1156 // 4a. Construct the target with the given new.target and argumentsList.
1157 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET);
1158
1159 // 4b. The target is not a constructor, throw an appropriate TypeError.
1160 __ bind(&target_not_constructor);
1161 {
1162 __ mov(Operand(esp, kPointerSize), edi);
1163 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1, 1);
1164 }
1165
1166 // 4c. The new.target is not a constructor, throw an appropriate TypeError.
1167 __ bind(&new_target_not_constructor);
1168 {
1169 __ mov(Operand(esp, kPointerSize), edx);
1170 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1, 1);
1171 }
1172 }
1173
1174
1175 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { 1157 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) {
1176 // ----------- S t a t e ------------- 1158 // ----------- S t a t e -------------
1177 // -- eax : argc 1159 // -- eax : argc
1178 // -- esp[0] : return address 1160 // -- esp[0] : return address
1179 // -- esp[4] : last argument 1161 // -- esp[4] : last argument
1180 // ----------------------------------- 1162 // -----------------------------------
1181 Label generic_array_code; 1163 Label generic_array_code;
1182 1164
1183 // Get the InternalArray function. 1165 // Get the InternalArray function.
1184 __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi); 1166 __ LoadGlobalFunction(Context::INTERNAL_ARRAY_FUNCTION_INDEX, edi);
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 __ leave(); 1415 __ leave();
1434 1416
1435 // Remove caller arguments from the stack. 1417 // Remove caller arguments from the stack.
1436 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 1418 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
1437 __ pop(ecx); 1419 __ pop(ecx);
1438 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver 1420 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver
1439 __ push(ecx); 1421 __ push(ecx);
1440 } 1422 }
1441 1423
1442 1424
1443 // static
1444 void Builtins::Generate_Apply(MacroAssembler* masm) {
1445 // ----------- S t a t e -------------
1446 // -- eax : argumentsList
1447 // -- edi : target
1448 // -- edx : new.target (checked to be constructor or undefined)
1449 // -- esp[0] : return address.
1450 // -- esp[4] : thisArgument
1451 // -----------------------------------
1452
1453 // Create the list of arguments from the array-like argumentsList.
1454 {
1455 Label create_arguments, create_array, create_runtime, done_create;
1456 __ JumpIfSmi(eax, &create_runtime);
1457
1458 // Load the map of argumentsList into ecx.
1459 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
1460
1461 // Load native context into ebx.
1462 __ mov(ebx, NativeContextOperand());
1463
1464 // Check if argumentsList is an (unmodified) arguments object.
1465 __ cmp(ecx, ContextOperand(ebx, Context::SLOPPY_ARGUMENTS_MAP_INDEX));
1466 __ j(equal, &create_arguments);
1467 __ cmp(ecx, ContextOperand(ebx, Context::STRICT_ARGUMENTS_MAP_INDEX));
1468 __ j(equal, &create_arguments);
1469
1470 // Check if argumentsList is a fast JSArray.
1471 __ CmpInstanceType(ecx, JS_ARRAY_TYPE);
1472 __ j(equal, &create_array);
1473
1474 // Ask the runtime to create the list (actually a FixedArray).
1475 __ bind(&create_runtime);
1476 {
1477 FrameScope scope(masm, StackFrame::INTERNAL);
1478 __ Push(edi);
1479 __ Push(edx);
1480 __ Push(eax);
1481 __ CallRuntime(Runtime::kCreateListFromArrayLike, 1);
1482 __ Pop(edx);
1483 __ Pop(edi);
1484 __ mov(ebx, FieldOperand(eax, FixedArray::kLengthOffset));
1485 __ SmiUntag(ebx);
1486 }
1487 __ jmp(&done_create);
1488
1489 // Try to create the list from an arguments object.
1490 __ bind(&create_arguments);
1491 __ mov(ebx,
1492 FieldOperand(eax, JSObject::kHeaderSize +
1493 Heap::kArgumentsLengthIndex * kPointerSize));
1494 __ mov(ecx, FieldOperand(eax, JSObject::kElementsOffset));
1495 __ cmp(ebx, FieldOperand(ecx, FixedArray::kLengthOffset));
1496 __ j(not_equal, &create_runtime);
1497 __ SmiUntag(ebx);
1498 __ mov(eax, ecx);
1499 __ jmp(&done_create);
1500
1501 // Try to create the list from a JSArray object.
1502 __ bind(&create_array);
1503 __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
1504 __ DecodeField<Map::ElementsKindBits>(ecx);
1505 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
1506 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
1507 STATIC_ASSERT(FAST_ELEMENTS == 2);
1508 __ cmp(ecx, Immediate(FAST_ELEMENTS));
1509 __ j(above, &create_runtime);
1510 __ cmp(ecx, Immediate(FAST_HOLEY_SMI_ELEMENTS));
1511 __ j(equal, &create_runtime);
1512 __ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset));
1513 __ SmiUntag(ebx);
1514 __ mov(eax, FieldOperand(eax, JSArray::kElementsOffset));
1515
1516 __ bind(&done_create);
1517 }
1518
1519 // Check for stack overflow.
1520 {
1521 // Check the stack for overflow. We are not trying to catch interruptions
1522 // (i.e. debug break and preemption) here, so check the "real stack limit".
1523 Label done;
1524 ExternalReference real_stack_limit =
1525 ExternalReference::address_of_real_stack_limit(masm->isolate());
1526 __ mov(ecx, Operand::StaticVariable(real_stack_limit));
1527 // Make ecx the space we have left. The stack might already be overflowed
1528 // here which will cause ecx to become negative.
1529 __ neg(ecx);
1530 __ add(ecx, esp);
1531 __ sar(ecx, kPointerSizeLog2);
1532 // Check if the arguments will overflow the stack.
1533 __ cmp(ecx, ebx);
1534 __ j(greater, &done, Label::kNear); // Signed comparison.
1535 __ TailCallRuntime(Runtime::kThrowStackOverflow, 1, 1);
1536 __ bind(&done);
1537 }
1538
1539 // ----------- S t a t e -------------
1540 // -- edi : target
1541 // -- eax : args (a FixedArray built from argumentsList)
1542 // -- ebx : len (number of elements to push from args)
1543 // -- edx : new.target (checked to be constructor or undefined)
1544 // -- esp[0] : return address.
1545 // -- esp[4] : thisArgument
1546 // -----------------------------------
1547
1548 // Push arguments onto the stack (thisArgument is already on the stack).
1549 {
1550 __ movd(xmm0, edx);
1551 __ PopReturnAddressTo(edx);
1552 __ Move(ecx, Immediate(0));
1553 Label done, loop;
1554 __ bind(&loop);
1555 __ cmp(ecx, ebx);
1556 __ j(equal, &done, Label::kNear);
1557 __ Push(
1558 FieldOperand(eax, ecx, times_pointer_size, FixedArray::kHeaderSize));
1559 __ inc(ecx);
1560 __ jmp(&loop);
1561 __ bind(&done);
1562 __ PushReturnAddressFrom(edx);
1563 __ movd(edx, xmm0);
1564 __ Move(eax, ebx);
1565 }
1566
1567 // Dispatch to Call or Construct depending on whether new.target is undefined.
1568 {
1569 __ CompareRoot(edx, Heap::kUndefinedValueRootIndex);
1570 __ j(equal, masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
1571 __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
1572 }
1573 }
1574
1575
1576 // static 1425 // static
1577 void Builtins::Generate_CallFunction(MacroAssembler* masm, 1426 void Builtins::Generate_CallFunction(MacroAssembler* masm,
1578 ConvertReceiverMode mode) { 1427 ConvertReceiverMode mode) {
1579 // ----------- S t a t e ------------- 1428 // ----------- S t a t e -------------
1580 // -- eax : the number of arguments (not including the receiver) 1429 // -- eax : the number of arguments (not including the receiver)
1581 // -- edi : the function to call (checked to be a JSFunction) 1430 // -- edi : the function to call (checked to be a JSFunction)
1582 // ----------------------------------- 1431 // -----------------------------------
1583 __ AssertFunction(edi); 1432 __ AssertFunction(edi);
1584 1433
1585 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) 1434 // See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 1980
2132 __ bind(&ok); 1981 __ bind(&ok);
2133 __ ret(0); 1982 __ ret(0);
2134 } 1983 }
2135 1984
2136 #undef __ 1985 #undef __
2137 } // namespace internal 1986 } // namespace internal
2138 } // namespace v8 1987 } // namespace v8
2139 1988
2140 #endif // V8_TARGET_ARCH_IA32 1989 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/contexts.h ('k') | src/js/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698