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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 1166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 __ mov(Operand(esp, 2 * kPointerSize), ecx); | 1177 __ mov(Operand(esp, 2 * kPointerSize), ecx); |
1178 __ lea(edx, Operand(edx, ecx, times_2, | 1178 __ lea(edx, Operand(edx, ecx, times_2, |
1179 StandardFrameConstants::kCallerSPOffset)); | 1179 StandardFrameConstants::kCallerSPOffset)); |
1180 __ mov(Operand(esp, 3 * kPointerSize), edx); | 1180 __ mov(Operand(esp, 3 * kPointerSize), edx); |
1181 | 1181 |
1182 __ bind(&runtime); | 1182 __ bind(&runtime); |
1183 __ TailCallRuntime(Runtime::kNewRestParam, 3, 1); | 1183 __ TailCallRuntime(Runtime::kNewRestParam, 3, 1); |
1184 } | 1184 } |
1185 | 1185 |
1186 | 1186 |
| 1187 static void ThrowPendingException(MacroAssembler* masm) { |
| 1188 Isolate* isolate = masm->isolate(); |
| 1189 |
| 1190 ExternalReference pending_handler_context_address( |
| 1191 Isolate::kPendingHandlerContextAddress, isolate); |
| 1192 ExternalReference pending_handler_code_address( |
| 1193 Isolate::kPendingHandlerCodeAddress, isolate); |
| 1194 ExternalReference pending_handler_offset_address( |
| 1195 Isolate::kPendingHandlerOffsetAddress, isolate); |
| 1196 ExternalReference pending_handler_fp_address( |
| 1197 Isolate::kPendingHandlerFPAddress, isolate); |
| 1198 ExternalReference pending_handler_sp_address( |
| 1199 Isolate::kPendingHandlerSPAddress, isolate); |
| 1200 |
| 1201 // Ask the runtime for help to determine the handler. This will set eax to |
| 1202 // contain the current pending exception, don't clobber it. |
| 1203 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate); |
| 1204 __ mov(Operand(esp, 0 * kPointerSize), Immediate(0)); // argc. |
| 1205 __ mov(Operand(esp, 1 * kPointerSize), Immediate(0)); // argv. |
| 1206 __ mov(Operand(esp, 2 * kPointerSize), |
| 1207 Immediate(ExternalReference::isolate_address(isolate))); |
| 1208 __ mov(ebx, Immediate(find_handler)); |
| 1209 __ call(ebx); |
| 1210 |
| 1211 // Retrieve the handler context, SP and FP. |
| 1212 __ mov(esi, Operand::StaticVariable(pending_handler_context_address)); |
| 1213 __ mov(esp, Operand::StaticVariable(pending_handler_sp_address)); |
| 1214 __ mov(ebp, Operand::StaticVariable(pending_handler_fp_address)); |
| 1215 |
| 1216 // If the handler is a JS frame, restore the context to the frame. |
| 1217 // (kind == ENTRY) == (ebp == 0) == (esi == 0), so we could test either |
| 1218 // ebp or esi. |
| 1219 Label skip; |
| 1220 __ test(esi, esi); |
| 1221 __ j(zero, &skip, Label::kNear); |
| 1222 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); |
| 1223 __ bind(&skip); |
| 1224 |
| 1225 // Compute the handler entry address and jump to it. |
| 1226 __ mov(edi, Operand::StaticVariable(pending_handler_code_address)); |
| 1227 __ mov(edx, Operand::StaticVariable(pending_handler_offset_address)); |
| 1228 __ lea(edi, FieldOperand(edi, edx, times_1, Code::kHeaderSize)); |
| 1229 __ jmp(edi); |
| 1230 } |
| 1231 |
| 1232 |
1187 void RegExpExecStub::Generate(MacroAssembler* masm) { | 1233 void RegExpExecStub::Generate(MacroAssembler* masm) { |
1188 // Just jump directly to runtime if native RegExp is not selected at compile | 1234 // Just jump directly to runtime if native RegExp is not selected at compile |
1189 // time or if regexp entry in generated code is turned off runtime switch or | 1235 // time or if regexp entry in generated code is turned off runtime switch or |
1190 // at compilation. | 1236 // at compilation. |
1191 #ifdef V8_INTERPRETED_REGEXP | 1237 #ifdef V8_INTERPRETED_REGEXP |
1192 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); | 1238 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); |
1193 #else // V8_INTERPRETED_REGEXP | 1239 #else // V8_INTERPRETED_REGEXP |
1194 | 1240 |
1195 // Stack frame on entry. | 1241 // Stack frame on entry. |
1196 // esp[0]: return address | 1242 // esp[0]: return address |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1458 // Result must now be exception. If there is no pending exception already a | 1504 // Result must now be exception. If there is no pending exception already a |
1459 // stack overflow (on the backtrack stack) was detected in RegExp code but | 1505 // stack overflow (on the backtrack stack) was detected in RegExp code but |
1460 // haven't created the exception yet. Handle that in the runtime system. | 1506 // haven't created the exception yet. Handle that in the runtime system. |
1461 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 1507 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
1462 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, | 1508 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, |
1463 isolate()); | 1509 isolate()); |
1464 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | 1510 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); |
1465 __ mov(eax, Operand::StaticVariable(pending_exception)); | 1511 __ mov(eax, Operand::StaticVariable(pending_exception)); |
1466 __ cmp(edx, eax); | 1512 __ cmp(edx, eax); |
1467 __ j(equal, &runtime); | 1513 __ j(equal, &runtime); |
| 1514 |
1468 // For exception, throw the exception again. | 1515 // For exception, throw the exception again. |
1469 | 1516 __ EnterExitFrame(false); |
1470 // Clear the pending exception variable. | 1517 ThrowPendingException(masm); |
1471 __ mov(Operand::StaticVariable(pending_exception), edx); | |
1472 | |
1473 // Special handling of termination exceptions which are uncatchable | |
1474 // by javascript code. | |
1475 __ cmp(eax, factory->termination_exception()); | |
1476 Label throw_termination_exception; | |
1477 __ j(equal, &throw_termination_exception, Label::kNear); | |
1478 | |
1479 // Handle normal exception by following handler chain. | |
1480 __ Throw(eax); | |
1481 | |
1482 __ bind(&throw_termination_exception); | |
1483 __ ThrowUncatchable(eax); | |
1484 | 1518 |
1485 __ bind(&failure); | 1519 __ bind(&failure); |
1486 // For failure to match, return null. | 1520 // For failure to match, return null. |
1487 __ mov(eax, factory->null_value()); | 1521 __ mov(eax, factory->null_value()); |
1488 __ ret(4 * kPointerSize); | 1522 __ ret(4 * kPointerSize); |
1489 | 1523 |
1490 // Load RegExp data. | 1524 // Load RegExp data. |
1491 __ bind(&success); | 1525 __ bind(&success); |
1492 __ mov(eax, Operand(esp, kJSRegExpOffset)); | 1526 __ mov(eax, Operand(esp, kJSRegExpOffset)); |
1493 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); | 1527 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); |
(...skipping 1014 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2508 __ j(not_equal, &okay, Label::kNear); | 2542 __ j(not_equal, &okay, Label::kNear); |
2509 __ int3(); | 2543 __ int3(); |
2510 __ bind(&okay); | 2544 __ bind(&okay); |
2511 } | 2545 } |
2512 | 2546 |
2513 // Check result for exception sentinel. | 2547 // Check result for exception sentinel. |
2514 Label exception_returned; | 2548 Label exception_returned; |
2515 __ cmp(eax, isolate()->factory()->exception()); | 2549 __ cmp(eax, isolate()->factory()->exception()); |
2516 __ j(equal, &exception_returned); | 2550 __ j(equal, &exception_returned); |
2517 | 2551 |
2518 ExternalReference pending_exception_address( | |
2519 Isolate::kPendingExceptionAddress, isolate()); | |
2520 | |
2521 // Check that there is no pending exception, otherwise we | 2552 // Check that there is no pending exception, otherwise we |
2522 // should have returned the exception sentinel. | 2553 // should have returned the exception sentinel. |
2523 if (FLAG_debug_code) { | 2554 if (FLAG_debug_code) { |
2524 __ push(edx); | 2555 __ push(edx); |
2525 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | 2556 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); |
2526 Label okay; | 2557 Label okay; |
| 2558 ExternalReference pending_exception_address( |
| 2559 Isolate::kPendingExceptionAddress, isolate()); |
2527 __ cmp(edx, Operand::StaticVariable(pending_exception_address)); | 2560 __ cmp(edx, Operand::StaticVariable(pending_exception_address)); |
2528 // Cannot use check here as it attempts to generate call into runtime. | 2561 // Cannot use check here as it attempts to generate call into runtime. |
2529 __ j(equal, &okay, Label::kNear); | 2562 __ j(equal, &okay, Label::kNear); |
2530 __ int3(); | 2563 __ int3(); |
2531 __ bind(&okay); | 2564 __ bind(&okay); |
2532 __ pop(edx); | 2565 __ pop(edx); |
2533 } | 2566 } |
2534 | 2567 |
2535 // Exit the JavaScript to C++ exit frame. | 2568 // Exit the JavaScript to C++ exit frame. |
2536 __ LeaveExitFrame(save_doubles()); | 2569 __ LeaveExitFrame(save_doubles()); |
2537 __ ret(0); | 2570 __ ret(0); |
2538 | 2571 |
2539 // Handling of exception. | 2572 // Handling of exception. |
2540 __ bind(&exception_returned); | 2573 __ bind(&exception_returned); |
2541 | 2574 ThrowPendingException(masm); |
2542 // Retrieve the pending exception. | |
2543 __ mov(eax, Operand::StaticVariable(pending_exception_address)); | |
2544 | |
2545 // Clear the pending exception. | |
2546 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | |
2547 __ mov(Operand::StaticVariable(pending_exception_address), edx); | |
2548 | |
2549 // Special handling of termination exceptions which are uncatchable | |
2550 // by javascript code. | |
2551 Label throw_termination_exception; | |
2552 __ cmp(eax, isolate()->factory()->termination_exception()); | |
2553 __ j(equal, &throw_termination_exception); | |
2554 | |
2555 // Handle normal exception. | |
2556 __ Throw(eax); | |
2557 | |
2558 __ bind(&throw_termination_exception); | |
2559 __ ThrowUncatchable(eax); | |
2560 } | 2575 } |
2561 | 2576 |
2562 | 2577 |
2563 void JSEntryStub::Generate(MacroAssembler* masm) { | 2578 void JSEntryStub::Generate(MacroAssembler* masm) { |
2564 Label invoke, handler_entry, exit; | 2579 Label invoke, handler_entry, exit; |
2565 Label not_outermost_js, not_outermost_js_2; | 2580 Label not_outermost_js, not_outermost_js_2; |
2566 | 2581 |
2567 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 2582 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
2568 | 2583 |
2569 // Set up frame. | 2584 // Set up frame. |
(...skipping 2568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5138 ApiParameterOperand(2), kStackSpace, nullptr, | 5153 ApiParameterOperand(2), kStackSpace, nullptr, |
5139 Operand(ebp, 7 * kPointerSize), NULL); | 5154 Operand(ebp, 7 * kPointerSize), NULL); |
5140 } | 5155 } |
5141 | 5156 |
5142 | 5157 |
5143 #undef __ | 5158 #undef __ |
5144 | 5159 |
5145 } } // namespace v8::internal | 5160 } } // namespace v8::internal |
5146 | 5161 |
5147 #endif // V8_TARGET_ARCH_IA32 | 5162 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |