OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 16 matching lines...) Expand all Loading... |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 #include "codegen-inl.h" | 29 #include "codegen-inl.h" |
30 #include "macro-assembler.h" | 30 #include "macro-assembler.h" |
31 | 31 |
32 namespace v8 { | 32 namespace v8 { |
33 namespace internal { | 33 namespace internal { |
34 | 34 |
35 #define __ ACCESS_MASM(masm) | 35 #define __ ACCESS_MASM(masm) |
36 | 36 |
37 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) { | |
38 // TODO(428): Don't pass the function in a static variable. | |
39 ExternalReference passed = ExternalReference::builtin_passed_function(); | |
40 __ movq(kScratchRegister, passed.address(), RelocInfo::EXTERNAL_REFERENCE); | |
41 __ movq(Operand(kScratchRegister, 0), rdi); | |
42 | 37 |
43 // The actual argument count has already been loaded into register | 38 void Builtins::Generate_Adaptor(MacroAssembler* masm, |
44 // rax, but JumpToRuntime expects rax to contain the number of | 39 CFunctionId id, |
45 // arguments including the receiver. | 40 BuiltinExtraArguments extra_args) { |
46 __ incq(rax); | 41 // ----------- S t a t e ------------- |
| 42 // -- rax : number of arguments excluding receiver |
| 43 // -- rdi : called function (only guaranteed when |
| 44 // extra_args requires it) |
| 45 // -- rsi : context |
| 46 // -- rsp[0] : return address |
| 47 // -- rsp[4] : last argument |
| 48 // -- ... |
| 49 // -- rsp[4 * argc] : first argument (argc == rax) |
| 50 // -- rsp[4 * (argc +1)] : receiver |
| 51 // ----------------------------------- |
| 52 |
| 53 // Insert extra arguments. |
| 54 int num_extra_args = 0; |
| 55 if (extra_args == NEEDS_CALLED_FUNCTION) { |
| 56 num_extra_args = 1; |
| 57 __ pop(kScratchRegister); // Save return address. |
| 58 __ push(rdi); |
| 59 __ push(kScratchRegister); // Restore return address. |
| 60 } else { |
| 61 ASSERT(extra_args == NO_EXTRA_ARGUMENTS); |
| 62 } |
| 63 |
| 64 // JumpToRuntime expects rax to contain the number of arguments |
| 65 // including the receiver and the extra arguments. |
| 66 __ addq(rax, Immediate(num_extra_args + 1)); |
47 __ JumpToRuntime(ExternalReference(id), 1); | 67 __ JumpToRuntime(ExternalReference(id), 1); |
48 } | 68 } |
49 | 69 |
50 | 70 |
51 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | 71 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { |
52 __ push(rbp); | 72 __ push(rbp); |
53 __ movq(rbp, rsp); | 73 __ movq(rbp, rsp); |
54 | 74 |
55 // Store the arguments adaptor context sentinel. | 75 // Store the arguments adaptor context sentinel. |
56 __ Push(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); | 76 __ Push(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)); |
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
881 // eax: number of arguments | 901 // eax: number of arguments |
882 __ bind(&non_function_call); | 902 __ bind(&non_function_call); |
883 // Set expected number of arguments to zero (not changing eax). | 903 // Set expected number of arguments to zero (not changing eax). |
884 __ movq(rbx, Immediate(0)); | 904 __ movq(rbx, Immediate(0)); |
885 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 905 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); |
886 __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), | 906 __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), |
887 RelocInfo::CODE_TARGET); | 907 RelocInfo::CODE_TARGET); |
888 } | 908 } |
889 | 909 |
890 | 910 |
891 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 911 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
| 912 bool is_api_function) { |
892 // Enter a construct frame. | 913 // Enter a construct frame. |
893 __ EnterConstructFrame(); | 914 __ EnterConstructFrame(); |
894 | 915 |
895 // Store a smi-tagged arguments count on the stack. | 916 // Store a smi-tagged arguments count on the stack. |
896 __ Integer32ToSmi(rax, rax); | 917 __ Integer32ToSmi(rax, rax); |
897 __ push(rax); | 918 __ push(rax); |
898 | 919 |
899 // Push the function to invoke on the stack. | 920 // Push the function to invoke on the stack. |
900 __ push(rdi); | 921 __ push(rdi); |
901 | 922 |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1084 Label loop, entry; | 1105 Label loop, entry; |
1085 __ movq(rcx, rax); | 1106 __ movq(rcx, rax); |
1086 __ jmp(&entry); | 1107 __ jmp(&entry); |
1087 __ bind(&loop); | 1108 __ bind(&loop); |
1088 __ push(Operand(rbx, rcx, times_pointer_size, 0)); | 1109 __ push(Operand(rbx, rcx, times_pointer_size, 0)); |
1089 __ bind(&entry); | 1110 __ bind(&entry); |
1090 __ decq(rcx); | 1111 __ decq(rcx); |
1091 __ j(greater_equal, &loop); | 1112 __ j(greater_equal, &loop); |
1092 | 1113 |
1093 // Call the function. | 1114 // Call the function. |
1094 ParameterCount actual(rax); | 1115 if (is_api_function) { |
1095 __ InvokeFunction(rdi, actual, CALL_FUNCTION); | 1116 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
| 1117 Handle<Code> code = Handle<Code>( |
| 1118 Builtins::builtin(Builtins::HandleApiCallConstruct)); |
| 1119 ParameterCount expected(0); |
| 1120 __ InvokeCode(code, expected, expected, |
| 1121 RelocInfo::CODE_TARGET, CALL_FUNCTION); |
| 1122 } else { |
| 1123 ParameterCount actual(rax); |
| 1124 __ InvokeFunction(rdi, actual, CALL_FUNCTION); |
| 1125 } |
1096 | 1126 |
1097 // Restore context from the frame. | 1127 // Restore context from the frame. |
1098 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1128 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
1099 | 1129 |
1100 // If the result is an object (in the ECMA sense), we should get rid | 1130 // If the result is an object (in the ECMA sense), we should get rid |
1101 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 | 1131 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 |
1102 // on page 74. | 1132 // on page 74. |
1103 Label use_receiver, exit; | 1133 Label use_receiver, exit; |
1104 // If the result is a smi, it is *not* an object in the ECMA sense. | 1134 // If the result is a smi, it is *not* an object in the ECMA sense. |
1105 __ JumpIfSmi(rax, &use_receiver); | 1135 __ JumpIfSmi(rax, &use_receiver); |
(...skipping 16 matching lines...) Expand all Loading... |
1122 // Remove caller arguments from the stack and return. | 1152 // Remove caller arguments from the stack and return. |
1123 __ pop(rcx); | 1153 __ pop(rcx); |
1124 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); | 1154 SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2); |
1125 __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); | 1155 __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize)); |
1126 __ push(rcx); | 1156 __ push(rcx); |
1127 __ IncrementCounter(&Counters::constructed_objects, 1); | 1157 __ IncrementCounter(&Counters::constructed_objects, 1); |
1128 __ ret(0); | 1158 __ ret(0); |
1129 } | 1159 } |
1130 | 1160 |
1131 | 1161 |
| 1162 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
| 1163 Generate_JSConstructStubHelper(masm, false); |
| 1164 } |
| 1165 |
| 1166 |
| 1167 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
| 1168 Generate_JSConstructStubHelper(masm, true); |
| 1169 } |
| 1170 |
| 1171 |
1132 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 1172 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
1133 bool is_construct) { | 1173 bool is_construct) { |
1134 // Expects five C++ function parameters. | 1174 // Expects five C++ function parameters. |
1135 // - Address entry (ignored) | 1175 // - Address entry (ignored) |
1136 // - JSFunction* function ( | 1176 // - JSFunction* function ( |
1137 // - Object* receiver | 1177 // - Object* receiver |
1138 // - int argc | 1178 // - int argc |
1139 // - Object*** argv | 1179 // - Object*** argv |
1140 // (see Handle::Invoke in execution.cc). | 1180 // (see Handle::Invoke in execution.cc). |
1141 | 1181 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1246 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 1286 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
1247 Generate_JSEntryTrampolineHelper(masm, false); | 1287 Generate_JSEntryTrampolineHelper(masm, false); |
1248 } | 1288 } |
1249 | 1289 |
1250 | 1290 |
1251 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 1291 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
1252 Generate_JSEntryTrampolineHelper(masm, true); | 1292 Generate_JSEntryTrampolineHelper(masm, true); |
1253 } | 1293 } |
1254 | 1294 |
1255 } } // namespace v8::internal | 1295 } } // namespace v8::internal |
OLD | NEW |