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 { |
| 1205 FrameScope scope(masm, StackFrame::MANUAL); |
| 1206 __ PrepareCallCFunction(3, eax); |
| 1207 __ mov(Operand(esp, 0 * kPointerSize), Immediate(0)); // argc. |
| 1208 __ mov(Operand(esp, 1 * kPointerSize), Immediate(0)); // argv. |
| 1209 __ mov(Operand(esp, 2 * kPointerSize), |
| 1210 Immediate(ExternalReference::isolate_address(isolate))); |
| 1211 __ CallCFunction(find_handler, 3); |
| 1212 } |
| 1213 |
| 1214 // Retrieve the handler context, SP and FP. |
| 1215 __ mov(esi, Operand::StaticVariable(pending_handler_context_address)); |
| 1216 __ mov(esp, Operand::StaticVariable(pending_handler_sp_address)); |
| 1217 __ mov(ebp, Operand::StaticVariable(pending_handler_fp_address)); |
| 1218 |
| 1219 // If the handler is a JS frame, restore the context to the frame. |
| 1220 // (kind == ENTRY) == (ebp == 0) == (esi == 0), so we could test either |
| 1221 // ebp or esi. |
| 1222 Label skip; |
| 1223 __ test(esi, esi); |
| 1224 __ j(zero, &skip, Label::kNear); |
| 1225 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); |
| 1226 __ bind(&skip); |
| 1227 |
| 1228 // Compute the handler entry address and jump to it. |
| 1229 __ mov(edi, Operand::StaticVariable(pending_handler_code_address)); |
| 1230 __ mov(edx, Operand::StaticVariable(pending_handler_offset_address)); |
| 1231 __ lea(edi, FieldOperand(edi, edx, times_1, Code::kHeaderSize)); |
| 1232 __ jmp(edi); |
| 1233 } |
| 1234 |
| 1235 |
1187 void RegExpExecStub::Generate(MacroAssembler* masm) { | 1236 void RegExpExecStub::Generate(MacroAssembler* masm) { |
1188 // Just jump directly to runtime if native RegExp is not selected at compile | 1237 // 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 | 1238 // time or if regexp entry in generated code is turned off runtime switch or |
1190 // at compilation. | 1239 // at compilation. |
1191 #ifdef V8_INTERPRETED_REGEXP | 1240 #ifdef V8_INTERPRETED_REGEXP |
1192 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); | 1241 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); |
1193 #else // V8_INTERPRETED_REGEXP | 1242 #else // V8_INTERPRETED_REGEXP |
1194 | 1243 |
1195 // Stack frame on entry. | 1244 // Stack frame on entry. |
1196 // esp[0]: return address | 1245 // 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 | 1507 // 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 | 1508 // 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. | 1509 // haven't created the exception yet. Handle that in the runtime system. |
1461 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 1510 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
1462 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, | 1511 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, |
1463 isolate()); | 1512 isolate()); |
1464 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | 1513 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); |
1465 __ mov(eax, Operand::StaticVariable(pending_exception)); | 1514 __ mov(eax, Operand::StaticVariable(pending_exception)); |
1466 __ cmp(edx, eax); | 1515 __ cmp(edx, eax); |
1467 __ j(equal, &runtime); | 1516 __ j(equal, &runtime); |
| 1517 |
1468 // For exception, throw the exception again. | 1518 // For exception, throw the exception again. |
1469 | 1519 __ EnterExitFrame(false); |
1470 // Clear the pending exception variable. | 1520 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 | 1521 |
1485 __ bind(&failure); | 1522 __ bind(&failure); |
1486 // For failure to match, return null. | 1523 // For failure to match, return null. |
1487 __ mov(eax, factory->null_value()); | 1524 __ mov(eax, factory->null_value()); |
1488 __ ret(4 * kPointerSize); | 1525 __ ret(4 * kPointerSize); |
1489 | 1526 |
1490 // Load RegExp data. | 1527 // Load RegExp data. |
1491 __ bind(&success); | 1528 __ bind(&success); |
1492 __ mov(eax, Operand(esp, kJSRegExpOffset)); | 1529 __ mov(eax, Operand(esp, kJSRegExpOffset)); |
1493 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); | 1530 __ 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); | 2545 __ j(not_equal, &okay, Label::kNear); |
2509 __ int3(); | 2546 __ int3(); |
2510 __ bind(&okay); | 2547 __ bind(&okay); |
2511 } | 2548 } |
2512 | 2549 |
2513 // Check result for exception sentinel. | 2550 // Check result for exception sentinel. |
2514 Label exception_returned; | 2551 Label exception_returned; |
2515 __ cmp(eax, isolate()->factory()->exception()); | 2552 __ cmp(eax, isolate()->factory()->exception()); |
2516 __ j(equal, &exception_returned); | 2553 __ j(equal, &exception_returned); |
2517 | 2554 |
2518 ExternalReference pending_exception_address( | |
2519 Isolate::kPendingExceptionAddress, isolate()); | |
2520 | |
2521 // Check that there is no pending exception, otherwise we | 2555 // Check that there is no pending exception, otherwise we |
2522 // should have returned the exception sentinel. | 2556 // should have returned the exception sentinel. |
2523 if (FLAG_debug_code) { | 2557 if (FLAG_debug_code) { |
2524 __ push(edx); | 2558 __ push(edx); |
2525 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | 2559 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); |
2526 Label okay; | 2560 Label okay; |
| 2561 ExternalReference pending_exception_address( |
| 2562 Isolate::kPendingExceptionAddress, isolate()); |
2527 __ cmp(edx, Operand::StaticVariable(pending_exception_address)); | 2563 __ cmp(edx, Operand::StaticVariable(pending_exception_address)); |
2528 // Cannot use check here as it attempts to generate call into runtime. | 2564 // Cannot use check here as it attempts to generate call into runtime. |
2529 __ j(equal, &okay, Label::kNear); | 2565 __ j(equal, &okay, Label::kNear); |
2530 __ int3(); | 2566 __ int3(); |
2531 __ bind(&okay); | 2567 __ bind(&okay); |
2532 __ pop(edx); | 2568 __ pop(edx); |
2533 } | 2569 } |
2534 | 2570 |
2535 // Exit the JavaScript to C++ exit frame. | 2571 // Exit the JavaScript to C++ exit frame. |
2536 __ LeaveExitFrame(save_doubles()); | 2572 __ LeaveExitFrame(save_doubles()); |
2537 __ ret(0); | 2573 __ ret(0); |
2538 | 2574 |
2539 // Handling of exception. | 2575 // Handling of exception. |
2540 __ bind(&exception_returned); | 2576 __ bind(&exception_returned); |
2541 | 2577 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 } | 2578 } |
2561 | 2579 |
2562 | 2580 |
2563 void JSEntryStub::Generate(MacroAssembler* masm) { | 2581 void JSEntryStub::Generate(MacroAssembler* masm) { |
2564 Label invoke, handler_entry, exit; | 2582 Label invoke, handler_entry, exit; |
2565 Label not_outermost_js, not_outermost_js_2; | 2583 Label not_outermost_js, not_outermost_js_2; |
2566 | 2584 |
2567 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 2585 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
2568 | 2586 |
2569 // Set up frame. | 2587 // Set up frame. |
(...skipping 2568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5138 ApiParameterOperand(2), kStackSpace, nullptr, | 5156 ApiParameterOperand(2), kStackSpace, nullptr, |
5139 Operand(ebp, 7 * kPointerSize), NULL); | 5157 Operand(ebp, 7 * kPointerSize), NULL); |
5140 } | 5158 } |
5141 | 5159 |
5142 | 5160 |
5143 #undef __ | 5161 #undef __ |
5144 | 5162 |
5145 } } // namespace v8::internal | 5163 } } // namespace v8::internal |
5146 | 5164 |
5147 #endif // V8_TARGET_ARCH_IA32 | 5165 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |