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 #include "src/assembler.h" | 7 #include "src/assembler.h" |
8 #include "src/ast.h" | 8 #include "src/ast.h" |
9 #include "src/regexp-macro-assembler.h" | 9 #include "src/regexp-macro-assembler.h" |
10 #include "src/regexp-stack.h" | 10 #include "src/regexp-stack.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 } | 35 } |
36 | 36 |
37 | 37 |
38 bool NativeRegExpMacroAssembler::CanReadUnaligned() { | 38 bool NativeRegExpMacroAssembler::CanReadUnaligned() { |
39 return FLAG_enable_unaligned_accesses && !slow_safe(); | 39 return FLAG_enable_unaligned_accesses && !slow_safe(); |
40 } | 40 } |
41 | 41 |
42 const byte* NativeRegExpMacroAssembler::StringCharacterPosition( | 42 const byte* NativeRegExpMacroAssembler::StringCharacterPosition( |
43 String* subject, | 43 String* subject, |
44 int start_index) { | 44 int start_index) { |
45 // Not just flat, but ultra flat. | 45 if (subject->IsConsString()) { |
46 DCHECK(subject->IsExternalString() || subject->IsSeqString()); | 46 subject = ConsString::cast(subject)->first(); |
| 47 } else if (subject->IsSlicedString()) { |
| 48 start_index += SlicedString::cast(subject)->offset(); |
| 49 subject = SlicedString::cast(subject)->parent(); |
| 50 } |
47 DCHECK(start_index >= 0); | 51 DCHECK(start_index >= 0); |
48 DCHECK(start_index <= subject->length()); | 52 DCHECK(start_index <= subject->length()); |
49 if (subject->IsOneByteRepresentation()) { | 53 if (subject->IsSeqOneByteString()) { |
50 const byte* address; | 54 return reinterpret_cast<const byte*>( |
51 if (StringShape(subject).IsExternal()) { | 55 SeqOneByteString::cast(subject)->GetChars() + start_index); |
52 const uint8_t* data = ExternalOneByteString::cast(subject)->GetChars(); | 56 } else if (subject->IsSeqTwoByteString()) { |
53 address = reinterpret_cast<const byte*>(data); | 57 return reinterpret_cast<const byte*>( |
54 } else { | 58 SeqTwoByteString::cast(subject)->GetChars() + start_index); |
55 DCHECK(subject->IsSeqOneByteString()); | 59 } else if (subject->IsExternalOneByteString()) { |
56 const uint8_t* data = SeqOneByteString::cast(subject)->GetChars(); | 60 return reinterpret_cast<const byte*>( |
57 address = reinterpret_cast<const byte*>(data); | 61 ExternalOneByteString::cast(subject)->GetChars() + start_index); |
58 } | 62 } else { |
59 return address + start_index; | 63 return reinterpret_cast<const byte*>( |
| 64 ExternalTwoByteString::cast(subject)->GetChars() + start_index); |
60 } | 65 } |
61 const uc16* data; | |
62 if (StringShape(subject).IsExternal()) { | |
63 data = ExternalTwoByteString::cast(subject)->GetChars(); | |
64 } else { | |
65 DCHECK(subject->IsSeqTwoByteString()); | |
66 data = SeqTwoByteString::cast(subject)->GetChars(); | |
67 } | |
68 return reinterpret_cast<const byte*>(data + start_index); | |
69 } | 66 } |
70 | 67 |
71 | 68 |
| 69 int NativeRegExpMacroAssembler::CheckStackGuardState( |
| 70 Isolate* isolate, int start_index, bool is_direct_call, |
| 71 Address* return_address, Code* re_code, String** subject, |
| 72 const byte** input_start, const byte** input_end) { |
| 73 DCHECK(re_code->instruction_start() <= *return_address); |
| 74 DCHECK(*return_address <= re_code->instruction_end()); |
| 75 int return_value = 0; |
| 76 // Prepare for possible GC. |
| 77 HandleScope handles(isolate); |
| 78 Handle<Code> code_handle(re_code); |
| 79 Handle<String> subject_handle(*subject); |
| 80 bool is_one_byte = subject_handle->IsOneByteRepresentationUnderneath(); |
| 81 |
| 82 StackLimitCheck check(isolate); |
| 83 if (check.JsHasOverflowed()) { |
| 84 isolate->StackOverflow(); |
| 85 return_value = EXCEPTION; |
| 86 } else if (is_direct_call) { |
| 87 // If not real stack overflow the stack guard was used to interrupt |
| 88 // execution for another purpose. If this is a direct call from JavaScript |
| 89 // retry the RegExp forcing the call through the runtime system. |
| 90 // Currently the direct call cannot handle a GC. |
| 91 return_value = RETRY; |
| 92 } else { |
| 93 Object* result = isolate->stack_guard()->HandleInterrupts(); |
| 94 if (result->IsException()) return_value = EXCEPTION; |
| 95 } |
| 96 |
| 97 DisallowHeapAllocation no_gc; |
| 98 |
| 99 if (*code_handle != re_code) { // Return address no longer valid |
| 100 intptr_t delta = code_handle->address() - re_code->address(); |
| 101 // Overwrite the return address on the stack. |
| 102 *return_address += delta; |
| 103 } |
| 104 |
| 105 // If we continue, we need to update the subject string addresses. |
| 106 if (return_value == 0) { |
| 107 // String encoding might have changed. |
| 108 if (subject_handle->IsOneByteRepresentationUnderneath() != is_one_byte) { |
| 109 // If we changed between an LATIN1 and an UC16 string, the specialized |
| 110 // code cannot be used, and we need to restart regexp matching from |
| 111 // scratch (including, potentially, compiling a new version of the code). |
| 112 return_value = RETRY; |
| 113 } else { |
| 114 *subject = *subject_handle; |
| 115 intptr_t byte_length = *input_end - *input_start; |
| 116 *input_start = StringCharacterPosition(*subject, start_index); |
| 117 *input_end = *input_start + byte_length; |
| 118 } |
| 119 } |
| 120 return return_value; |
| 121 } |
| 122 |
| 123 |
72 NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match( | 124 NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match( |
73 Handle<Code> regexp_code, | 125 Handle<Code> regexp_code, |
74 Handle<String> subject, | 126 Handle<String> subject, |
75 int* offsets_vector, | 127 int* offsets_vector, |
76 int offsets_vector_length, | 128 int offsets_vector_length, |
77 int previous_index, | 129 int previous_index, |
78 Isolate* isolate) { | 130 Isolate* isolate) { |
79 | 131 |
80 DCHECK(subject->IsFlat()); | 132 DCHECK(subject->IsFlat()); |
81 DCHECK(previous_index >= 0); | 133 DCHECK(previous_index >= 0); |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 return NULL; | 301 return NULL; |
250 } | 302 } |
251 *stack_base = new_stack_base; | 303 *stack_base = new_stack_base; |
252 intptr_t stack_content_size = old_stack_base - stack_pointer; | 304 intptr_t stack_content_size = old_stack_base - stack_pointer; |
253 return new_stack_base - stack_content_size; | 305 return new_stack_base - stack_content_size; |
254 } | 306 } |
255 | 307 |
256 #endif // V8_INTERPRETED_REGEXP | 308 #endif // V8_INTERPRETED_REGEXP |
257 | 309 |
258 } } // namespace v8::internal | 310 } } // namespace v8::internal |
OLD | NEW |