| 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 |