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 21 matching lines...) Expand all Loading... | |
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, | 37 void Builtins::Generate_Adaptor(MacroAssembler* masm, |
38 Builtins::CFunctionId id) { | 38 Builtins::CFunctionId id) { |
39 masm->int3(); // UNIMPLEMENTED. | 39 masm->int3(); // UNIMPLEMENTED. |
40 } | 40 } |
41 | 41 |
42 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) { | |
43 __ push(rbp); | |
44 __ movq(rbp, rsp); | |
45 | |
46 // Store the arguments adaptor context sentinel. | |
47 __ push(Immediate(ArgumentsAdaptorFrame::SENTINEL)); | |
48 | |
49 // Push the function on the stack. | |
50 __ push(rdi); | |
51 | |
52 // Preserve the number of arguments on the stack. Must preserve both | |
53 // eax and ebx because these registers are used when copying the | |
54 // arguments and the receiver. | |
55 ASSERT(kSmiTagSize == 1); | |
56 __ lea(rcx, Operand(rax, rax, kTimes1, kSmiTag)); | |
57 __ push(rcx); | |
58 } | |
59 | |
60 | |
61 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) { | |
62 // Retrieve the number of arguments from the stack. Number is a Smi. | |
63 __ movq(rbx, Operand(rbp, ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
64 | |
65 // Leave the frame. | |
66 __ movq(rsp, rbp); | |
67 __ pop(rbp); | |
68 | |
69 // Remove caller arguments from the stack. | |
70 // rbx holds a Smi. | |
William Hesse
2009/06/11 09:32:29
holds a Smi. Therefore, we convert to a dword off
| |
71 ASSERT_EQ(kSmiTagSize, 1 && kSmiTag == 0); | |
72 ASSERT_EQ(kPointerSize, (1 << kSmiTagSize) * 4); | |
73 __ pop(rcx); | |
74 __ lea(rsp, Operand(rsp, rbx, kTimes4, 1 * kPointerSize)); // 1 ~ receiver | |
75 __ push(rcx); | |
76 } | |
77 | |
78 | |
42 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { | 79 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) { |
43 masm->int3(); // UNIMPLEMENTED. | 80 // ----------- S t a t e ------------- |
81 // -- rax : actual number of arguments | |
82 // -- rbx : expected number of arguments | |
83 // -- rdx : code entry to call | |
84 // ----------------------------------- | |
85 | |
86 Label invoke, dont_adapt_arguments; | |
87 __ IncrementCounter(&Counters::arguments_adaptors, 1); | |
88 | |
89 Label enough, too_few; | |
90 __ cmp(rax, rbx); | |
91 __ j(less, &too_few); | |
92 __ cmp(rbx, Immediate(SharedFunctionInfo::kDontAdaptArgumentsSentinel)); | |
93 __ j(equal, &dont_adapt_arguments); | |
94 | |
95 { // Enough parameters: Actual >= expected. | |
96 __ bind(&enough); | |
97 EnterArgumentsAdaptorFrame(masm); | |
98 | |
99 // Copy receiver and all expected arguments. | |
100 const int offset = StandardFrameConstants::kCallerSPOffset; | |
101 __ lea(rax, Operand(rbp, rax, kTimesPointerSize, offset)); | |
102 __ movq(rcx, Immediate(-1)); // account for receiver | |
103 | |
104 Label copy; | |
105 __ bind(©); | |
106 __ inc(rcx); | |
107 __ push(Operand(rax, 0)); | |
108 __ sub(rax, Immediate(kPointerSize)); | |
109 __ cmp(rcx, rbx); | |
110 __ j(less, ©); | |
111 __ jmp(&invoke); | |
112 } | |
113 | |
114 { // Too few parameters: Actual < expected. | |
115 __ bind(&too_few); | |
116 EnterArgumentsAdaptorFrame(masm); | |
117 | |
118 // Copy receiver and all actual arguments. | |
119 const int offset = StandardFrameConstants::kCallerSPOffset; | |
120 __ lea(rdi, Operand(rbp, rax, kTimesPointerSize, offset)); | |
121 __ movq(rcx, Immediate(-1)); // account for receiver | |
122 | |
123 Label copy; | |
124 __ bind(©); | |
125 __ inc(rcx); | |
126 __ push(Operand(rdi, 0)); | |
127 __ sub(rdi, Immediate(kPointerSize)); | |
128 __ cmp(rcx, rax); | |
129 __ j(less, ©); | |
130 | |
131 // Fill remaining expected arguments with undefined values. | |
132 Label fill; | |
133 __ movq(kScratchRegister, | |
134 Factory::undefined_value(), | |
135 RelocInfo::EMBEDDED_OBJECT); | |
136 __ bind(&fill); | |
137 __ inc(rcx); | |
138 __ push(kScratchRegister); | |
139 __ cmp(rcx, rbx); | |
140 __ j(less, &fill); | |
141 | |
142 // Restore function pointer. | |
143 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | |
144 } | |
145 | |
146 // Call the entry point. | |
147 __ bind(&invoke); | |
148 __ call(rdx); | |
149 | |
150 // Leave frame and return. | |
151 LeaveArgumentsAdaptorFrame(masm); | |
152 __ ret(0); | |
153 | |
154 // ------------------------------------------- | |
155 // Dont adapt arguments. | |
156 // ------------------------------------------- | |
157 __ bind(&dont_adapt_arguments); | |
158 __ jmp(rdx); | |
44 } | 159 } |
45 | 160 |
161 | |
46 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 162 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
47 masm->int3(); // UNIMPLEMENTED. | 163 masm->int3(); // UNIMPLEMENTED. |
48 } | 164 } |
49 | 165 |
50 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { | 166 void Builtins::Generate_FunctionCall(MacroAssembler* masm) { |
51 masm->int3(); // UNIMPLEMENTED. | 167 masm->int3(); // UNIMPLEMENTED. |
52 } | 168 } |
53 | 169 |
54 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) { | 170 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) { |
55 masm->int3(); // UNIMPLEMENTED. | 171 masm->int3(); // UNIMPLEMENTED. |
(...skipping 19 matching lines...) Expand all Loading... | |
75 // rdx : function | 191 // rdx : function |
76 // r8 : receiver | 192 // r8 : receiver |
77 // r9 : argc | 193 // r9 : argc |
78 // [rsp+0x20] : argv | 194 // [rsp+0x20] : argv |
79 | 195 |
80 // Clear the context before we push it when entering the JS frame. | 196 // Clear the context before we push it when entering the JS frame. |
81 __ xor_(rsi, rsi); | 197 __ xor_(rsi, rsi); |
82 // Enter an internal frame. | 198 // Enter an internal frame. |
83 __ EnterInternalFrame(); | 199 __ EnterInternalFrame(); |
84 | 200 |
85 | |
86 // Load the function context into rsi. | 201 // Load the function context into rsi. |
87 __ movq(rsi, FieldOperand(rdx, JSFunction::kContextOffset)); | 202 __ movq(rsi, FieldOperand(rdx, JSFunction::kContextOffset)); |
88 | 203 |
89 // Push the function and the receiver onto the stack. | 204 // Push the function and the receiver onto the stack. |
90 __ push(rdx); | 205 __ push(rdx); |
91 __ push(r8); | 206 __ push(r8); |
92 | 207 |
93 // Load the number of arguments and setup pointer to the arguments. | 208 // Load the number of arguments and setup pointer to the arguments. |
94 __ movq(rax, r9); | 209 __ movq(rax, r9); |
95 // Load the previous frame pointer to access C argument on stack | 210 // Load the previous frame pointer to access C argument on stack |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
148 | 263 |
149 // Invoke the code. | 264 // Invoke the code. |
150 if (is_construct) { | 265 if (is_construct) { |
151 // Expects rdi to hold function pointer. | 266 // Expects rdi to hold function pointer. |
152 __ movq(kScratchRegister, | 267 __ movq(kScratchRegister, |
153 Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)), | 268 Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)), |
154 RelocInfo::CODE_TARGET); | 269 RelocInfo::CODE_TARGET); |
155 __ call(kScratchRegister); | 270 __ call(kScratchRegister); |
156 } else { | 271 } else { |
157 ParameterCount actual(rax); | 272 ParameterCount actual(rax); |
273 // Function must be in rdi. | |
158 __ InvokeFunction(rdi, actual, CALL_FUNCTION); | 274 __ InvokeFunction(rdi, actual, CALL_FUNCTION); |
159 } | 275 } |
160 | 276 |
161 // Exit the JS frame. Notice that this also removes the empty | 277 // Exit the JS frame. Notice that this also removes the empty |
162 // context and the function left on the stack by the code | 278 // context and the function left on the stack by the code |
163 // invocation. | 279 // invocation. |
164 __ LeaveInternalFrame(); | 280 __ LeaveInternalFrame(); |
165 // TODO(X64): Is argument correct? Is there a receiver to remove? | 281 // TODO(X64): Is argument correct? Is there a receiver to remove? |
166 __ ret(1 * kPointerSize); // remove receiver | 282 __ ret(1 * kPointerSize); // remove receiver |
167 } | 283 } |
168 | 284 |
169 | 285 |
170 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 286 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
171 Generate_JSEntryTrampolineHelper(masm, false); | 287 Generate_JSEntryTrampolineHelper(masm, false); |
172 } | 288 } |
173 | 289 |
174 | 290 |
175 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 291 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
176 Generate_JSEntryTrampolineHelper(masm, true); | 292 Generate_JSEntryTrampolineHelper(masm, true); |
177 } | 293 } |
178 | 294 |
179 } } // namespace v8::internal | 295 } } // namespace v8::internal |
180 | 296 |
181 | 297 |
OLD | NEW |