| 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/regexp/regexp-macro-assembler.h" | 5 #include "src/regexp/regexp-macro-assembler.h" |
| 6 | 6 |
| 7 #include "src/assembler.h" | 7 #include "src/assembler.h" |
| 8 #include "src/isolate-inl.h" | 8 #include "src/isolate-inl.h" |
| 9 #include "src/regexp/regexp-stack.h" | 9 #include "src/regexp/regexp-stack.h" |
| 10 #include "src/simulator.h" | 10 #include "src/simulator.h" |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 | 158 |
| 159 int NativeRegExpMacroAssembler::CheckStackGuardState( | 159 int NativeRegExpMacroAssembler::CheckStackGuardState( |
| 160 Isolate* isolate, int start_index, bool is_direct_call, | 160 Isolate* isolate, int start_index, bool is_direct_call, |
| 161 Address* return_address, Code* re_code, String** subject, | 161 Address* return_address, Code* re_code, String** subject, |
| 162 const byte** input_start, const byte** input_end) { | 162 const byte** input_start, const byte** input_end) { |
| 163 DCHECK(re_code->instruction_start() <= *return_address); | 163 DCHECK(re_code->instruction_start() <= *return_address); |
| 164 DCHECK(*return_address <= re_code->instruction_end()); | 164 DCHECK(*return_address <= re_code->instruction_end()); |
| 165 int return_value = 0; | 165 int return_value = 0; |
| 166 // Prepare for possible GC. | 166 // Prepare for possible GC. |
| 167 HandleScope handles(isolate); | 167 HandleScope handles(isolate); |
| 168 intptr_t return_address_offset = |
| 169 *return_address - re_code->instruction_start(); |
| 168 Handle<Code> code_handle(re_code); | 170 Handle<Code> code_handle(re_code); |
| 169 Handle<String> subject_handle(*subject); | 171 Handle<String> subject_handle(*subject); |
| 170 bool is_one_byte = subject_handle->IsOneByteRepresentationUnderneath(); | 172 bool is_one_byte = subject_handle->IsOneByteRepresentationUnderneath(); |
| 173 intptr_t byte_length = *input_end - *input_start; |
| 171 | 174 |
| 172 StackLimitCheck check(isolate); | 175 StackLimitCheck check(isolate); |
| 173 bool js_has_overflowed = check.JsHasOverflowed(); | 176 bool js_has_overflowed = check.JsHasOverflowed(); |
| 174 | 177 |
| 175 if (is_direct_call) { | 178 if (is_direct_call) { |
| 176 // Direct calls from JavaScript can be interrupted in two ways: | 179 // Direct calls from JavaScript can be interrupted in two ways: |
| 177 // 1. A real stack overflow, in which case we let the caller throw the | 180 // 1. A real stack overflow, in which case we let the caller throw the |
| 178 // exception. | 181 // exception. |
| 179 // 2. The stack guard was used to interrupt execution for another purpose, | 182 // 2. The stack guard was used to interrupt execution for another purpose, |
| 180 // forcing the call through the runtime system. | 183 // forcing the call through the runtime system. |
| 181 return_value = js_has_overflowed ? EXCEPTION : RETRY; | 184 return_value = js_has_overflowed ? EXCEPTION : RETRY; |
| 182 } else if (js_has_overflowed) { | 185 } else if (js_has_overflowed) { |
| 183 isolate->StackOverflow(); | 186 isolate->StackOverflow(); |
| 184 return_value = EXCEPTION; | 187 return_value = EXCEPTION; |
| 185 } else { | 188 } else { |
| 186 Object* result = isolate->stack_guard()->HandleInterrupts(); | 189 Object* result = isolate->stack_guard()->HandleInterrupts(); |
| 187 if (result->IsException(isolate)) return_value = EXCEPTION; | 190 if (result->IsException(isolate)) return_value = EXCEPTION; |
| 188 } | 191 } |
| 189 | 192 |
| 190 DisallowHeapAllocation no_gc; | 193 DisallowHeapAllocation no_gc; |
| 191 | 194 |
| 192 if (*code_handle != re_code) { // Return address no longer valid | 195 // Fix up the return address (it might be no longer valid after GC). |
| 193 intptr_t delta = code_handle->address() - re_code->address(); | 196 *return_address = code_handle->instruction_start() + return_address_offset; |
| 194 // Overwrite the return address on the stack. | |
| 195 *return_address += delta; | |
| 196 } | |
| 197 | 197 |
| 198 // If we continue, we need to update the subject string addresses. | 198 // If we continue, we need to update the subject string addresses. |
| 199 if (return_value == 0) { | 199 if (return_value == 0) { |
| 200 // String encoding might have changed. | 200 // String encoding might have changed. |
| 201 if (subject_handle->IsOneByteRepresentationUnderneath() != is_one_byte) { | 201 if (subject_handle->IsOneByteRepresentationUnderneath() != is_one_byte) { |
| 202 // If we changed between an LATIN1 and an UC16 string, the specialized | 202 // If we changed between an LATIN1 and an UC16 string, the specialized |
| 203 // code cannot be used, and we need to restart regexp matching from | 203 // code cannot be used, and we need to restart regexp matching from |
| 204 // scratch (including, potentially, compiling a new version of the code). | 204 // scratch (including, potentially, compiling a new version of the code). |
| 205 return_value = RETRY; | 205 return_value = RETRY; |
| 206 } else { | 206 } else { |
| 207 *subject = *subject_handle; | 207 *subject = *subject_handle; |
| 208 intptr_t byte_length = *input_end - *input_start; | |
| 209 *input_start = StringCharacterPosition(*subject, start_index); | 208 *input_start = StringCharacterPosition(*subject, start_index); |
| 210 *input_end = *input_start + byte_length; | 209 *input_end = *input_start + byte_length; |
| 211 } | 210 } |
| 212 } | 211 } |
| 213 return return_value; | 212 return return_value; |
| 214 } | 213 } |
| 215 | 214 |
| 216 | 215 |
| 217 NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match( | 216 NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match( |
| 218 Handle<Code> regexp_code, | 217 Handle<Code> regexp_code, |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 } | 356 } |
| 358 *stack_base = new_stack_base; | 357 *stack_base = new_stack_base; |
| 359 intptr_t stack_content_size = old_stack_base - stack_pointer; | 358 intptr_t stack_content_size = old_stack_base - stack_pointer; |
| 360 return new_stack_base - stack_content_size; | 359 return new_stack_base - stack_content_size; |
| 361 } | 360 } |
| 362 | 361 |
| 363 #endif // V8_INTERPRETED_REGEXP | 362 #endif // V8_INTERPRETED_REGEXP |
| 364 | 363 |
| 365 } // namespace internal | 364 } // namespace internal |
| 366 } // namespace v8 | 365 } // namespace v8 |
| OLD | NEW |