OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalContextOffset)); | 465 __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalContextOffset)); |
466 __ mov(ebx, FieldOperand(ebx, kGlobalIndex)); | 466 __ mov(ebx, FieldOperand(ebx, kGlobalIndex)); |
467 __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); | 467 __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset)); |
468 | 468 |
469 __ bind(&patch_receiver); | 469 __ bind(&patch_receiver); |
470 __ mov(Operand(esp, eax, times_4, 0), ebx); | 470 __ mov(Operand(esp, eax, times_4, 0), ebx); |
471 | 471 |
472 __ bind(&done); | 472 __ bind(&done); |
473 } | 473 } |
474 | 474 |
475 // 4. Shift stuff one slot down the stack. | 475 // 4. Check that the function really is a function. |
| 476 { Label done; |
| 477 __ test(edi, Operand(edi)); |
| 478 __ j(not_zero, &done, taken); |
| 479 __ xor_(ebx, Operand(ebx)); |
| 480 // CALL_NON_FUNCTION will expect to find the non-function callee on the |
| 481 // expression stack of the caller. Transfer it from receiver to the |
| 482 // caller's expression stack (and make the first argument the receiver |
| 483 // for CALL_NON_FUNCTION) by decrementing the argument count. |
| 484 __ dec(eax); |
| 485 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
| 486 __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), |
| 487 RelocInfo::CODE_TARGET); |
| 488 __ bind(&done); |
| 489 } |
| 490 |
| 491 // 5. Shift arguments and return address one slot down on the stack |
| 492 // (overwriting the receiver). |
476 { Label loop; | 493 { Label loop; |
477 __ lea(ecx, Operand(eax, +1)); // +1 ~ copy receiver too | 494 __ mov(ecx, eax); |
478 __ bind(&loop); | 495 __ bind(&loop); |
479 __ mov(ebx, Operand(esp, ecx, times_4, 0)); | 496 __ mov(ebx, Operand(esp, ecx, times_4, 0)); |
480 __ mov(Operand(esp, ecx, times_4, kPointerSize), ebx); | 497 __ mov(Operand(esp, ecx, times_4, kPointerSize), ebx); |
481 __ dec(ecx); | 498 __ dec(ecx); |
482 __ j(not_zero, &loop); | 499 __ j(not_sign, &loop); |
| 500 __ pop(ebx); // Discard copy of return address. |
| 501 __ dec(eax); // One fewer argument (first argument is new receiver). |
483 } | 502 } |
484 | 503 |
485 // 5. Remove TOS (copy of last arguments), but keep return address. | 504 // 6. Get the code to call from the function and check that the number of |
486 __ pop(ebx); | 505 // expected arguments matches what we're providing. |
487 __ pop(ecx); | 506 { __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
488 __ push(ebx); | |
489 __ dec(eax); | |
490 | |
491 // 6. Check that function really was a function and get the code to | |
492 // call from the function and check that the number of expected | |
493 // arguments matches what we're providing. | |
494 { Label invoke; | |
495 __ test(edi, Operand(edi)); | |
496 __ j(not_zero, &invoke, taken); | |
497 __ xor_(ebx, Operand(ebx)); | |
498 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); | |
499 __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)), | |
500 RelocInfo::CODE_TARGET); | |
501 | |
502 __ bind(&invoke); | |
503 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | |
504 __ mov(ebx, | 507 __ mov(ebx, |
505 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); | 508 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); |
506 __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset)); | 509 __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset)); |
507 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); | 510 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); |
508 __ cmp(eax, Operand(ebx)); | 511 __ cmp(eax, Operand(ebx)); |
509 __ j(not_equal, Handle<Code>(builtin(ArgumentsAdaptorTrampoline))); | 512 __ j(not_equal, Handle<Code>(builtin(ArgumentsAdaptorTrampoline))); |
510 } | 513 } |
511 | 514 |
512 // 7. Jump (tail-call) to the code in register edx without checking arguments. | 515 // 7. Jump (tail-call) to the code in register edx without checking arguments. |
513 ParameterCount expected(0); | 516 ParameterCount expected(0); |
(...skipping 697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 // Dont adapt arguments. | 1214 // Dont adapt arguments. |
1212 // ------------------------------------------- | 1215 // ------------------------------------------- |
1213 __ bind(&dont_adapt_arguments); | 1216 __ bind(&dont_adapt_arguments); |
1214 __ jmp(Operand(edx)); | 1217 __ jmp(Operand(edx)); |
1215 } | 1218 } |
1216 | 1219 |
1217 | 1220 |
1218 #undef __ | 1221 #undef __ |
1219 | 1222 |
1220 } } // namespace v8::internal | 1223 } } // namespace v8::internal |
OLD | NEW |