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_X87 | 7 #if V8_TARGET_ARCH_X87 |
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 847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 __ mov(Operand(esp, 2 * kPointerSize), ecx); | 858 __ mov(Operand(esp, 2 * kPointerSize), ecx); |
859 __ lea(edx, Operand(edx, ecx, times_2, | 859 __ lea(edx, Operand(edx, ecx, times_2, |
860 StandardFrameConstants::kCallerSPOffset)); | 860 StandardFrameConstants::kCallerSPOffset)); |
861 __ mov(Operand(esp, 3 * kPointerSize), edx); | 861 __ mov(Operand(esp, 3 * kPointerSize), edx); |
862 | 862 |
863 __ bind(&runtime); | 863 __ bind(&runtime); |
864 __ TailCallRuntime(Runtime::kNewRestParam, 3, 1); | 864 __ TailCallRuntime(Runtime::kNewRestParam, 3, 1); |
865 } | 865 } |
866 | 866 |
867 | 867 |
868 static void ThrowPendingException(MacroAssembler* masm) { | |
869 Isolate* isolate = masm->isolate(); | |
870 | |
871 ExternalReference pending_handler_context_address( | |
872 Isolate::kPendingHandlerContextAddress, isolate); | |
873 ExternalReference pending_handler_code_address( | |
874 Isolate::kPendingHandlerCodeAddress, isolate); | |
875 ExternalReference pending_handler_offset_address( | |
876 Isolate::kPendingHandlerOffsetAddress, isolate); | |
877 ExternalReference pending_handler_fp_address( | |
878 Isolate::kPendingHandlerFPAddress, isolate); | |
879 ExternalReference pending_handler_sp_address( | |
880 Isolate::kPendingHandlerSPAddress, isolate); | |
881 | |
882 // Ask the runtime for help to determine the handler. This will set eax to | |
883 // contain the current pending exception, don't clobber it. | |
884 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate); | |
885 { | |
886 FrameScope scope(masm, StackFrame::MANUAL); | |
887 __ PrepareCallCFunction(3, eax); | |
888 __ mov(Operand(esp, 0 * kPointerSize), Immediate(0)); // argc. | |
889 __ mov(Operand(esp, 1 * kPointerSize), Immediate(0)); // argv. | |
890 __ mov(Operand(esp, 2 * kPointerSize), | |
891 Immediate(ExternalReference::isolate_address(isolate))); | |
892 __ CallCFunction(find_handler, 3); | |
893 } | |
894 | |
895 // Retrieve the handler context, SP and FP. | |
896 __ mov(esi, Operand::StaticVariable(pending_handler_context_address)); | |
897 __ mov(esp, Operand::StaticVariable(pending_handler_sp_address)); | |
898 __ mov(ebp, Operand::StaticVariable(pending_handler_fp_address)); | |
899 | |
900 // If the handler is a JS frame, restore the context to the frame. | |
901 // (kind == ENTRY) == (ebp == 0) == (esi == 0), so we could test either | |
902 // ebp or esi. | |
903 Label skip; | |
904 __ test(esi, esi); | |
905 __ j(zero, &skip, Label::kNear); | |
906 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); | |
907 __ bind(&skip); | |
908 | |
909 // Compute the handler entry address and jump to it. | |
910 __ mov(edi, Operand::StaticVariable(pending_handler_code_address)); | |
911 __ mov(edx, Operand::StaticVariable(pending_handler_offset_address)); | |
912 __ lea(edi, FieldOperand(edi, edx, times_1, Code::kHeaderSize)); | |
913 __ jmp(edi); | |
914 } | |
915 | |
916 | |
917 void RegExpExecStub::Generate(MacroAssembler* masm) { | 868 void RegExpExecStub::Generate(MacroAssembler* masm) { |
918 // Just jump directly to runtime if native RegExp is not selected at compile | 869 // Just jump directly to runtime if native RegExp is not selected at compile |
919 // time or if regexp entry in generated code is turned off runtime switch or | 870 // time or if regexp entry in generated code is turned off runtime switch or |
920 // at compilation. | 871 // at compilation. |
921 #ifdef V8_INTERPRETED_REGEXP | 872 #ifdef V8_INTERPRETED_REGEXP |
922 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); | 873 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |
923 #else // V8_INTERPRETED_REGEXP | 874 #else // V8_INTERPRETED_REGEXP |
924 | 875 |
925 // Stack frame on entry. | 876 // Stack frame on entry. |
926 // esp[0]: return address | 877 // esp[0]: return address |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1190 // haven't created the exception yet. Handle that in the runtime system. | 1141 // haven't created the exception yet. Handle that in the runtime system. |
1191 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 1142 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
1192 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, | 1143 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, |
1193 isolate()); | 1144 isolate()); |
1194 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | 1145 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); |
1195 __ mov(eax, Operand::StaticVariable(pending_exception)); | 1146 __ mov(eax, Operand::StaticVariable(pending_exception)); |
1196 __ cmp(edx, eax); | 1147 __ cmp(edx, eax); |
1197 __ j(equal, &runtime); | 1148 __ j(equal, &runtime); |
1198 | 1149 |
1199 // For exception, throw the exception again. | 1150 // For exception, throw the exception again. |
1200 __ EnterExitFrame(false); | 1151 __ TailCallRuntime(Runtime::kRegExpExecReThrow, 4, 1); |
1201 ThrowPendingException(masm); | |
1202 | 1152 |
1203 __ bind(&failure); | 1153 __ bind(&failure); |
1204 // For failure to match, return null. | 1154 // For failure to match, return null. |
1205 __ mov(eax, factory->null_value()); | 1155 __ mov(eax, factory->null_value()); |
1206 __ ret(4 * kPointerSize); | 1156 __ ret(4 * kPointerSize); |
1207 | 1157 |
1208 // Load RegExp data. | 1158 // Load RegExp data. |
1209 __ bind(&success); | 1159 __ bind(&success); |
1210 __ mov(eax, Operand(esp, kJSRegExpOffset)); | 1160 __ mov(eax, Operand(esp, kJSRegExpOffset)); |
1211 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); | 1161 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); |
(...skipping 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2260 __ bind(&okay); | 2210 __ bind(&okay); |
2261 __ pop(edx); | 2211 __ pop(edx); |
2262 } | 2212 } |
2263 | 2213 |
2264 // Exit the JavaScript to C++ exit frame. | 2214 // Exit the JavaScript to C++ exit frame. |
2265 __ LeaveExitFrame(save_doubles()); | 2215 __ LeaveExitFrame(save_doubles()); |
2266 __ ret(0); | 2216 __ ret(0); |
2267 | 2217 |
2268 // Handling of exception. | 2218 // Handling of exception. |
2269 __ bind(&exception_returned); | 2219 __ bind(&exception_returned); |
2270 ThrowPendingException(masm); | 2220 |
| 2221 ExternalReference pending_handler_context_address( |
| 2222 Isolate::kPendingHandlerContextAddress, isolate()); |
| 2223 ExternalReference pending_handler_code_address( |
| 2224 Isolate::kPendingHandlerCodeAddress, isolate()); |
| 2225 ExternalReference pending_handler_offset_address( |
| 2226 Isolate::kPendingHandlerOffsetAddress, isolate()); |
| 2227 ExternalReference pending_handler_fp_address( |
| 2228 Isolate::kPendingHandlerFPAddress, isolate()); |
| 2229 ExternalReference pending_handler_sp_address( |
| 2230 Isolate::kPendingHandlerSPAddress, isolate()); |
| 2231 |
| 2232 // Ask the runtime for help to determine the handler. This will set eax to |
| 2233 // contain the current pending exception, don't clobber it. |
| 2234 ExternalReference find_handler(Runtime::kFindExceptionHandler, isolate()); |
| 2235 { |
| 2236 FrameScope scope(masm, StackFrame::MANUAL); |
| 2237 __ PrepareCallCFunction(3, eax); |
| 2238 __ mov(Operand(esp, 0 * kPointerSize), Immediate(0)); // argc. |
| 2239 __ mov(Operand(esp, 1 * kPointerSize), Immediate(0)); // argv. |
| 2240 __ mov(Operand(esp, 2 * kPointerSize), |
| 2241 Immediate(ExternalReference::isolate_address(isolate()))); |
| 2242 __ CallCFunction(find_handler, 3); |
| 2243 } |
| 2244 |
| 2245 // Retrieve the handler context, SP and FP. |
| 2246 __ mov(esi, Operand::StaticVariable(pending_handler_context_address)); |
| 2247 __ mov(esp, Operand::StaticVariable(pending_handler_sp_address)); |
| 2248 __ mov(ebp, Operand::StaticVariable(pending_handler_fp_address)); |
| 2249 |
| 2250 // If the handler is a JS frame, restore the context to the frame. |
| 2251 // (kind == ENTRY) == (ebp == 0) == (esi == 0), so we could test either |
| 2252 // ebp or esi. |
| 2253 Label skip; |
| 2254 __ test(esi, esi); |
| 2255 __ j(zero, &skip, Label::kNear); |
| 2256 __ mov(Operand(ebp, StandardFrameConstants::kContextOffset), esi); |
| 2257 __ bind(&skip); |
| 2258 |
| 2259 // Compute the handler entry address and jump to it. |
| 2260 __ mov(edi, Operand::StaticVariable(pending_handler_code_address)); |
| 2261 __ mov(edx, Operand::StaticVariable(pending_handler_offset_address)); |
| 2262 __ lea(edi, FieldOperand(edi, edx, times_1, Code::kHeaderSize)); |
| 2263 __ jmp(edi); |
2271 } | 2264 } |
2272 | 2265 |
2273 | 2266 |
2274 void JSEntryStub::Generate(MacroAssembler* masm) { | 2267 void JSEntryStub::Generate(MacroAssembler* masm) { |
2275 Label invoke, handler_entry, exit; | 2268 Label invoke, handler_entry, exit; |
2276 Label not_outermost_js, not_outermost_js_2; | 2269 Label not_outermost_js, not_outermost_js_2; |
2277 | 2270 |
2278 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 2271 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
2279 | 2272 |
2280 // Set up frame. | 2273 // Set up frame. |
(...skipping 2566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4847 ApiParameterOperand(2), kStackSpace, nullptr, | 4840 ApiParameterOperand(2), kStackSpace, nullptr, |
4848 Operand(ebp, 7 * kPointerSize), NULL); | 4841 Operand(ebp, 7 * kPointerSize), NULL); |
4849 } | 4842 } |
4850 | 4843 |
4851 | 4844 |
4852 #undef __ | 4845 #undef __ |
4853 | 4846 |
4854 } } // namespace v8::internal | 4847 } } // namespace v8::internal |
4855 | 4848 |
4856 #endif // V8_TARGET_ARCH_X87 | 4849 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |