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 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalContextOffset)); | 269 __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalContextOffset)); |
270 __ movq(rbx, FieldOperand(rbx, kGlobalIndex)); | 270 __ movq(rbx, FieldOperand(rbx, kGlobalIndex)); |
271 __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); | 271 __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset)); |
272 | 272 |
273 __ bind(&patch_receiver); | 273 __ bind(&patch_receiver); |
274 __ movq(Operand(rsp, rax, times_pointer_size, 0), rbx); | 274 __ movq(Operand(rsp, rax, times_pointer_size, 0), rbx); |
275 | 275 |
276 __ bind(&done); | 276 __ bind(&done); |
277 } | 277 } |
278 | 278 |
279 // 4. Shift stuff one slot down the stack. | 279 // 4. Check that the function really is a function. |
| 280 { Label real_function; |
| 281 __ testq(rdi, rdi); |
| 282 __ j(not_zero, &real_function); |
| 283 __ xor_(rbx, rbx); |
| 284 // CALL_NON_FUNCTION will expect to find the non-function callee on the |
| 285 // expression stack of the caller. Transfer it from receiver to the |
| 286 // caller's expression stack (and make the first argument the receiver |
| 287 // for CALL_NON_FUNCTION) by decrementing the argument count. |
| 288 __ decq(rax); |
| 289 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); |
| 290 __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), |
| 291 RelocInfo::CODE_TARGET); |
| 292 |
| 293 __ bind(&real_function); |
| 294 } |
| 295 |
| 296 // 5. Shift arguments and return address one slot down on the stack |
| 297 // (overwriting the receiver). |
280 { Label loop; | 298 { Label loop; |
281 __ lea(rcx, Operand(rax, +1)); // +1 ~ copy receiver too | 299 __ movq(rcx, rax); |
282 __ bind(&loop); | 300 __ bind(&loop); |
283 __ movq(rbx, Operand(rsp, rcx, times_pointer_size, 0)); | 301 __ movq(rbx, Operand(rsp, rcx, times_pointer_size, 0)); |
284 __ movq(Operand(rsp, rcx, times_pointer_size, 1 * kPointerSize), rbx); | 302 __ movq(Operand(rsp, rcx, times_pointer_size, 1 * kPointerSize), rbx); |
285 __ decq(rcx); | 303 __ decq(rcx); |
286 __ j(not_zero, &loop); | 304 __ j(not_sign, &loop); |
| 305 __ pop(rbx); // Discard copy of return address. |
| 306 __ decq(rax); // One fewer argument (first argument is new receiver). |
287 } | 307 } |
288 | 308 |
289 // 5. Remove TOS (copy of last arguments), but keep return address. | 309 // 6. Get the code to call from the function and check that the number of |
290 __ pop(rbx); | 310 // expected arguments matches what we're providing. |
291 __ pop(rcx); | 311 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); |
292 __ push(rbx); | 312 __ movsxlq(rbx, |
293 __ decq(rax); | 313 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); |
294 | 314 __ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset)); |
295 // 6. Check that function really was a function and get the code to | 315 __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize)); |
296 // call from the function and check that the number of expected | 316 __ cmpq(rax, rbx); |
297 // arguments matches what we're providing. | 317 __ j(not_equal, |
298 { Label invoke, trampoline; | 318 Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), |
299 __ testq(rdi, rdi); | 319 RelocInfo::CODE_TARGET); |
300 __ j(not_zero, &invoke); | |
301 __ xor_(rbx, rbx); | |
302 __ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION); | |
303 __ bind(&trampoline); | |
304 __ Jump(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), | |
305 RelocInfo::CODE_TARGET); | |
306 | |
307 __ bind(&invoke); | |
308 __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); | |
309 __ movsxlq(rbx, | |
310 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); | |
311 __ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset)); | |
312 __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize)); | |
313 __ cmpq(rax, rbx); | |
314 __ j(not_equal, &trampoline); | |
315 } | |
316 | 320 |
317 // 7. Jump (tail-call) to the code in register edx without checking arguments. | 321 // 7. Jump (tail-call) to the code in register edx without checking arguments. |
318 ParameterCount expected(0); | 322 ParameterCount expected(0); |
319 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION); | 323 __ InvokeCode(rdx, expected, expected, JUMP_FUNCTION); |
320 } | 324 } |
321 | 325 |
322 | 326 |
323 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 327 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
324 // Stack at entry: | 328 // Stack at entry: |
325 // rsp: return address | 329 // rsp: return address |
(...skipping 960 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1286 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { | 1290 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) { |
1287 Generate_JSEntryTrampolineHelper(masm, false); | 1291 Generate_JSEntryTrampolineHelper(masm, false); |
1288 } | 1292 } |
1289 | 1293 |
1290 | 1294 |
1291 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { | 1295 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
1292 Generate_JSEntryTrampolineHelper(masm, true); | 1296 Generate_JSEntryTrampolineHelper(masm, true); |
1293 } | 1297 } |
1294 | 1298 |
1295 } } // namespace v8::internal | 1299 } } // namespace v8::internal |
OLD | NEW |