OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 2285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2296 // ebp: frame pointer (restored after C call) | 2296 // ebp: frame pointer (restored after C call) |
2297 // esp: stack pointer (restored after C call) | 2297 // esp: stack pointer (restored after C call) |
2298 // esi: current context (C callee-saved) | 2298 // esi: current context (C callee-saved) |
2299 // edi: JS function of the caller (C callee-saved) | 2299 // edi: JS function of the caller (C callee-saved) |
2300 // | 2300 // |
2301 // If argv_in_register(): | 2301 // If argv_in_register(): |
2302 // ecx: pointer to the first argument | 2302 // ecx: pointer to the first argument |
2303 | 2303 |
2304 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 2304 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
2305 | 2305 |
| 2306 // Reserve space on the stack for the three arguments passed to the call. If |
| 2307 // result size is greater than can be returned in registers, also reserve |
| 2308 // space for the hidden argument for the result location, and space for the |
| 2309 // result itself. |
| 2310 int arg_stack_space = result_size() < 3 ? 3 : 4 + result_size(); |
| 2311 |
2306 // Enter the exit frame that transitions from JavaScript to C++. | 2312 // Enter the exit frame that transitions from JavaScript to C++. |
2307 if (argv_in_register()) { | 2313 if (argv_in_register()) { |
2308 DCHECK(!save_doubles()); | 2314 DCHECK(!save_doubles()); |
2309 __ EnterApiExitFrame(3); | 2315 __ EnterApiExitFrame(arg_stack_space); |
2310 | 2316 |
2311 // Move argc and argv into the correct registers. | 2317 // Move argc and argv into the correct registers. |
2312 __ mov(esi, ecx); | 2318 __ mov(esi, ecx); |
2313 __ mov(edi, eax); | 2319 __ mov(edi, eax); |
2314 } else { | 2320 } else { |
2315 __ EnterExitFrame(save_doubles()); | 2321 __ EnterExitFrame(arg_stack_space, save_doubles()); |
2316 } | 2322 } |
2317 | 2323 |
2318 // ebx: pointer to C function (C callee-saved) | 2324 // ebx: pointer to C function (C callee-saved) |
2319 // ebp: frame pointer (restored after C call) | 2325 // ebp: frame pointer (restored after C call) |
2320 // esp: stack pointer (restored after C call) | 2326 // esp: stack pointer (restored after C call) |
2321 // edi: number of arguments including receiver (C callee-saved) | 2327 // edi: number of arguments including receiver (C callee-saved) |
2322 // esi: pointer to the first argument (C callee-saved) | 2328 // esi: pointer to the first argument (C callee-saved) |
2323 | 2329 |
2324 // Result returned in eax, or eax+edx if result size is 2. | 2330 // Result returned in eax, or eax+edx if result size is 2. |
2325 | 2331 |
2326 // Check stack alignment. | 2332 // Check stack alignment. |
2327 if (FLAG_debug_code) { | 2333 if (FLAG_debug_code) { |
2328 __ CheckStackAlignment(); | 2334 __ CheckStackAlignment(); |
2329 } | 2335 } |
| 2336 // Call C function. |
| 2337 if (result_size() <= 2) { |
| 2338 __ mov(Operand(esp, 0 * kPointerSize), edi); // argc. |
| 2339 __ mov(Operand(esp, 1 * kPointerSize), esi); // argv. |
| 2340 __ mov(Operand(esp, 2 * kPointerSize), |
| 2341 Immediate(ExternalReference::isolate_address(isolate()))); |
| 2342 } else { |
| 2343 DCHECK_EQ(3, result_size()); |
| 2344 // Pass a pointer to the result location as the first argument. |
| 2345 __ lea(eax, Operand(esp, 4 * kPointerSize)); |
| 2346 __ mov(Operand(esp, 0 * kPointerSize), eax); |
| 2347 __ mov(Operand(esp, 1 * kPointerSize), edi); // argc. |
| 2348 __ mov(Operand(esp, 2 * kPointerSize), esi); // argv. |
| 2349 __ mov(Operand(esp, 3 * kPointerSize), |
| 2350 Immediate(ExternalReference::isolate_address(isolate()))); |
| 2351 } |
| 2352 __ call(ebx); |
2330 | 2353 |
2331 // Call C function. | 2354 if (result_size() > 2) { |
2332 __ mov(Operand(esp, 0 * kPointerSize), edi); // argc. | 2355 DCHECK_EQ(3, result_size()); |
2333 __ mov(Operand(esp, 1 * kPointerSize), esi); // argv. | 2356 #ifndef _WIN32 |
2334 __ mov(Operand(esp, 2 * kPointerSize), | 2357 // Restore the "hidden" argument on the stack which was popped by caller. |
2335 Immediate(ExternalReference::isolate_address(isolate()))); | 2358 __ sub(esp, Immediate(kPointerSize)); |
2336 __ call(ebx); | 2359 #endif |
2337 // Result is in eax or edx:eax - do not destroy these registers! | 2360 // Read result values stored on stack. Result is stored above the arguments. |
| 2361 __ mov(kReturnRegister0, Operand(esp, 4 * kPointerSize)); |
| 2362 __ mov(kReturnRegister1, Operand(esp, 5 * kPointerSize)); |
| 2363 __ mov(kReturnRegister2, Operand(esp, 6 * kPointerSize)); |
| 2364 } |
| 2365 // Result is in eax, edx:eax or edi:edx:eax - do not destroy these registers! |
2338 | 2366 |
2339 // Check result for exception sentinel. | 2367 // Check result for exception sentinel. |
2340 Label exception_returned; | 2368 Label exception_returned; |
2341 __ cmp(eax, isolate()->factory()->exception()); | 2369 __ cmp(eax, isolate()->factory()->exception()); |
2342 __ j(equal, &exception_returned); | 2370 __ j(equal, &exception_returned); |
2343 | 2371 |
2344 // Check that there is no pending exception, otherwise we | 2372 // Check that there is no pending exception, otherwise we |
2345 // should have returned the exception sentinel. | 2373 // should have returned the exception sentinel. |
2346 if (FLAG_debug_code) { | 2374 if (FLAG_debug_code) { |
2347 __ push(edx); | 2375 __ push(edx); |
(...skipping 3322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5670 Operand(ebp, 7 * kPointerSize), NULL); | 5698 Operand(ebp, 7 * kPointerSize), NULL); |
5671 } | 5699 } |
5672 | 5700 |
5673 | 5701 |
5674 #undef __ | 5702 #undef __ |
5675 | 5703 |
5676 } // namespace internal | 5704 } // namespace internal |
5677 } // namespace v8 | 5705 } // namespace v8 |
5678 | 5706 |
5679 #endif // V8_TARGET_ARCH_IA32 | 5707 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |