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 ThrowPendingException(masm); |
Jarin
2015/02/27 07:49:14
Out of curiosity, how is the uncatchable exception
| |
1470 // Clear the pending exception variable. | |
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 | 1517 |
1485 __ bind(&failure); | 1518 __ bind(&failure); |
1486 // For failure to match, return null. | 1519 // For failure to match, return null. |
1487 __ mov(eax, factory->null_value()); | 1520 __ mov(eax, factory->null_value()); |
1488 __ ret(4 * kPointerSize); | 1521 __ ret(4 * kPointerSize); |
1489 | 1522 |
1490 // Load RegExp data. | 1523 // Load RegExp data. |
1491 __ bind(&success); | 1524 __ bind(&success); |
1492 __ mov(eax, Operand(esp, kJSRegExpOffset)); | 1525 __ mov(eax, Operand(esp, kJSRegExpOffset)); |
1493 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); | 1526 __ 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); | 2541 __ j(not_equal, &okay, Label::kNear); |
2509 __ int3(); | 2542 __ int3(); |
2510 __ bind(&okay); | 2543 __ bind(&okay); |
2511 } | 2544 } |
2512 | 2545 |
2513 // Check result for exception sentinel. | 2546 // Check result for exception sentinel. |
2514 Label exception_returned; | 2547 Label exception_returned; |
2515 __ cmp(eax, isolate()->factory()->exception()); | 2548 __ cmp(eax, isolate()->factory()->exception()); |
2516 __ j(equal, &exception_returned); | 2549 __ j(equal, &exception_returned); |
2517 | 2550 |
2518 ExternalReference pending_exception_address( | |
2519 Isolate::kPendingExceptionAddress, isolate()); | |
2520 | |
2521 // Check that there is no pending exception, otherwise we | 2551 // Check that there is no pending exception, otherwise we |
2522 // should have returned the exception sentinel. | 2552 // should have returned the exception sentinel. |
2523 if (FLAG_debug_code) { | 2553 if (FLAG_debug_code) { |
2524 __ push(edx); | 2554 __ push(edx); |
2525 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | 2555 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); |
2526 Label okay; | 2556 Label okay; |
2557 ExternalReference pending_exception_address( | |
2558 Isolate::kPendingExceptionAddress, isolate()); | |
2527 __ cmp(edx, Operand::StaticVariable(pending_exception_address)); | 2559 __ cmp(edx, Operand::StaticVariable(pending_exception_address)); |
2528 // Cannot use check here as it attempts to generate call into runtime. | 2560 // Cannot use check here as it attempts to generate call into runtime. |
2529 __ j(equal, &okay, Label::kNear); | 2561 __ j(equal, &okay, Label::kNear); |
2530 __ int3(); | 2562 __ int3(); |
2531 __ bind(&okay); | 2563 __ bind(&okay); |
2532 __ pop(edx); | 2564 __ pop(edx); |
2533 } | 2565 } |
2534 | 2566 |
2535 // Exit the JavaScript to C++ exit frame. | 2567 // Exit the JavaScript to C++ exit frame. |
2536 __ LeaveExitFrame(save_doubles()); | 2568 __ LeaveExitFrame(save_doubles()); |
2537 __ ret(0); | 2569 __ ret(0); |
2538 | 2570 |
2539 // Handling of exception. | 2571 // Handling of exception. |
2540 __ bind(&exception_returned); | 2572 __ bind(&exception_returned); |
2541 | 2573 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 } | 2574 } |
2561 | 2575 |
2562 | 2576 |
2563 void JSEntryStub::Generate(MacroAssembler* masm) { | 2577 void JSEntryStub::Generate(MacroAssembler* masm) { |
2564 Label invoke, handler_entry, exit; | 2578 Label invoke, handler_entry, exit; |
2565 Label not_outermost_js, not_outermost_js_2; | 2579 Label not_outermost_js, not_outermost_js_2; |
2566 | 2580 |
2567 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 2581 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
2568 | 2582 |
2569 // Set up frame. | 2583 // Set up frame. |
(...skipping 2568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5138 ApiParameterOperand(2), kStackSpace, nullptr, | 5152 ApiParameterOperand(2), kStackSpace, nullptr, |
5139 Operand(ebp, 7 * kPointerSize), NULL); | 5153 Operand(ebp, 7 * kPointerSize), NULL); |
5140 } | 5154 } |
5141 | 5155 |
5142 | 5156 |
5143 #undef __ | 5157 #undef __ |
5144 | 5158 |
5145 } } // namespace v8::internal | 5159 } } // namespace v8::internal |
5146 | 5160 |
5147 #endif // V8_TARGET_ARCH_IA32 | 5161 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |