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 |
868 void RegExpExecStub::Generate(MacroAssembler* masm) { | 917 void RegExpExecStub::Generate(MacroAssembler* masm) { |
869 // Just jump directly to runtime if native RegExp is not selected at compile | 918 // Just jump directly to runtime if native RegExp is not selected at compile |
870 // time or if regexp entry in generated code is turned off runtime switch or | 919 // time or if regexp entry in generated code is turned off runtime switch or |
871 // at compilation. | 920 // at compilation. |
872 #ifdef V8_INTERPRETED_REGEXP | 921 #ifdef V8_INTERPRETED_REGEXP |
873 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); | 922 __ TailCallRuntime(Runtime::kRegExpExecRT, 4, 1); |
874 #else // V8_INTERPRETED_REGEXP | 923 #else // V8_INTERPRETED_REGEXP |
875 | 924 |
876 // Stack frame on entry. | 925 // Stack frame on entry. |
877 // esp[0]: return address | 926 // esp[0]: return address |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1139 // Result must now be exception. If there is no pending exception already a | 1188 // Result must now be exception. If there is no pending exception already a |
1140 // stack overflow (on the backtrack stack) was detected in RegExp code but | 1189 // stack overflow (on the backtrack stack) was detected in RegExp code but |
1141 // haven't created the exception yet. Handle that in the runtime system. | 1190 // haven't created the exception yet. Handle that in the runtime system. |
1142 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 1191 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
1143 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, | 1192 ExternalReference pending_exception(Isolate::kPendingExceptionAddress, |
1144 isolate()); | 1193 isolate()); |
1145 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | 1194 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); |
1146 __ mov(eax, Operand::StaticVariable(pending_exception)); | 1195 __ mov(eax, Operand::StaticVariable(pending_exception)); |
1147 __ cmp(edx, eax); | 1196 __ cmp(edx, eax); |
1148 __ j(equal, &runtime); | 1197 __ j(equal, &runtime); |
| 1198 |
1149 // For exception, throw the exception again. | 1199 // For exception, throw the exception again. |
1150 | 1200 __ EnterExitFrame(false); |
1151 // Clear the pending exception variable. | 1201 ThrowPendingException(masm); |
1152 __ mov(Operand::StaticVariable(pending_exception), edx); | |
1153 | |
1154 // Special handling of termination exceptions which are uncatchable | |
1155 // by javascript code. | |
1156 __ cmp(eax, factory->termination_exception()); | |
1157 Label throw_termination_exception; | |
1158 __ j(equal, &throw_termination_exception, Label::kNear); | |
1159 | |
1160 // Handle normal exception by following handler chain. | |
1161 __ Throw(eax); | |
1162 | |
1163 __ bind(&throw_termination_exception); | |
1164 __ ThrowUncatchable(eax); | |
1165 | 1202 |
1166 __ bind(&failure); | 1203 __ bind(&failure); |
1167 // For failure to match, return null. | 1204 // For failure to match, return null. |
1168 __ mov(eax, factory->null_value()); | 1205 __ mov(eax, factory->null_value()); |
1169 __ ret(4 * kPointerSize); | 1206 __ ret(4 * kPointerSize); |
1170 | 1207 |
1171 // Load RegExp data. | 1208 // Load RegExp data. |
1172 __ bind(&success); | 1209 __ bind(&success); |
1173 __ mov(eax, Operand(esp, kJSRegExpOffset)); | 1210 __ mov(eax, Operand(esp, kJSRegExpOffset)); |
1174 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); | 1211 __ mov(ecx, FieldOperand(eax, JSRegExp::kDataOffset)); |
(...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2201 __ j(not_equal, &okay, Label::kNear); | 2238 __ j(not_equal, &okay, Label::kNear); |
2202 __ int3(); | 2239 __ int3(); |
2203 __ bind(&okay); | 2240 __ bind(&okay); |
2204 } | 2241 } |
2205 | 2242 |
2206 // Check result for exception sentinel. | 2243 // Check result for exception sentinel. |
2207 Label exception_returned; | 2244 Label exception_returned; |
2208 __ cmp(eax, isolate()->factory()->exception()); | 2245 __ cmp(eax, isolate()->factory()->exception()); |
2209 __ j(equal, &exception_returned); | 2246 __ j(equal, &exception_returned); |
2210 | 2247 |
2211 ExternalReference pending_exception_address( | |
2212 Isolate::kPendingExceptionAddress, isolate()); | |
2213 | |
2214 // Check that there is no pending exception, otherwise we | 2248 // Check that there is no pending exception, otherwise we |
2215 // should have returned the exception sentinel. | 2249 // should have returned the exception sentinel. |
2216 if (FLAG_debug_code) { | 2250 if (FLAG_debug_code) { |
2217 __ push(edx); | 2251 __ push(edx); |
2218 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | 2252 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); |
2219 Label okay; | 2253 Label okay; |
| 2254 ExternalReference pending_exception_address( |
| 2255 Isolate::kPendingExceptionAddress, isolate()); |
2220 __ cmp(edx, Operand::StaticVariable(pending_exception_address)); | 2256 __ cmp(edx, Operand::StaticVariable(pending_exception_address)); |
2221 // Cannot use check here as it attempts to generate call into runtime. | 2257 // Cannot use check here as it attempts to generate call into runtime. |
2222 __ j(equal, &okay, Label::kNear); | 2258 __ j(equal, &okay, Label::kNear); |
2223 __ int3(); | 2259 __ int3(); |
2224 __ bind(&okay); | 2260 __ bind(&okay); |
2225 __ pop(edx); | 2261 __ pop(edx); |
2226 } | 2262 } |
2227 | 2263 |
2228 // Exit the JavaScript to C++ exit frame. | 2264 // Exit the JavaScript to C++ exit frame. |
2229 __ LeaveExitFrame(save_doubles()); | 2265 __ LeaveExitFrame(save_doubles()); |
2230 __ ret(0); | 2266 __ ret(0); |
2231 | 2267 |
2232 // Handling of exception. | 2268 // Handling of exception. |
2233 __ bind(&exception_returned); | 2269 __ bind(&exception_returned); |
2234 | 2270 ThrowPendingException(masm); |
2235 // Retrieve the pending exception. | |
2236 __ mov(eax, Operand::StaticVariable(pending_exception_address)); | |
2237 | |
2238 // Clear the pending exception. | |
2239 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | |
2240 __ mov(Operand::StaticVariable(pending_exception_address), edx); | |
2241 | |
2242 // Special handling of termination exceptions which are uncatchable | |
2243 // by javascript code. | |
2244 Label throw_termination_exception; | |
2245 __ cmp(eax, isolate()->factory()->termination_exception()); | |
2246 __ j(equal, &throw_termination_exception); | |
2247 | |
2248 // Handle normal exception. | |
2249 __ Throw(eax); | |
2250 | |
2251 __ bind(&throw_termination_exception); | |
2252 __ ThrowUncatchable(eax); | |
2253 } | 2271 } |
2254 | 2272 |
2255 | 2273 |
2256 void JSEntryStub::Generate(MacroAssembler* masm) { | 2274 void JSEntryStub::Generate(MacroAssembler* masm) { |
2257 Label invoke, handler_entry, exit; | 2275 Label invoke, handler_entry, exit; |
2258 Label not_outermost_js, not_outermost_js_2; | 2276 Label not_outermost_js, not_outermost_js_2; |
2259 | 2277 |
2260 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 2278 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
2261 | 2279 |
2262 // Set up frame. | 2280 // Set up frame. |
(...skipping 2548 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4811 ApiParameterOperand(2), kStackSpace, nullptr, | 4829 ApiParameterOperand(2), kStackSpace, nullptr, |
4812 Operand(ebp, 7 * kPointerSize), NULL); | 4830 Operand(ebp, 7 * kPointerSize), NULL); |
4813 } | 4831 } |
4814 | 4832 |
4815 | 4833 |
4816 #undef __ | 4834 #undef __ |
4817 | 4835 |
4818 } } // namespace v8::internal | 4836 } } // namespace v8::internal |
4819 | 4837 |
4820 #endif // V8_TARGET_ARCH_X87 | 4838 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |