OLD | NEW |
1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 } | 98 } |
99 return reinterpret_cast<const byte*>(data + start_index); | 99 return reinterpret_cast<const byte*>(data + start_index); |
100 } | 100 } |
101 | 101 |
102 | 102 |
103 NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match( | 103 NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Match( |
104 Handle<Code> regexp_code, | 104 Handle<Code> regexp_code, |
105 Handle<String> subject, | 105 Handle<String> subject, |
106 int* offsets_vector, | 106 int* offsets_vector, |
107 int offsets_vector_length, | 107 int offsets_vector_length, |
108 int previous_index) { | 108 int previous_index, |
| 109 Isolate* isolate) { |
109 | 110 |
110 ASSERT(subject->IsFlat()); | 111 ASSERT(subject->IsFlat()); |
111 ASSERT(previous_index >= 0); | 112 ASSERT(previous_index >= 0); |
112 ASSERT(previous_index <= subject->length()); | 113 ASSERT(previous_index <= subject->length()); |
113 | 114 |
114 // No allocations before calling the regexp, but we can't use | 115 // No allocations before calling the regexp, but we can't use |
115 // AssertNoAllocation, since regexps might be preempted, and another thread | 116 // AssertNoAllocation, since regexps might be preempted, and another thread |
116 // might do allocation anyway. | 117 // might do allocation anyway. |
117 | 118 |
118 String* subject_ptr = *subject; | 119 String* subject_ptr = *subject; |
(...skipping 16 matching lines...) Expand all Loading... |
135 | 136 |
136 const byte* input_start = | 137 const byte* input_start = |
137 StringCharacterPosition(subject_ptr, start_offset); | 138 StringCharacterPosition(subject_ptr, start_offset); |
138 int byte_length = char_length << char_size_shift; | 139 int byte_length = char_length << char_size_shift; |
139 const byte* input_end = input_start + byte_length; | 140 const byte* input_end = input_start + byte_length; |
140 Result res = Execute(*regexp_code, | 141 Result res = Execute(*regexp_code, |
141 subject_ptr, | 142 subject_ptr, |
142 start_offset, | 143 start_offset, |
143 input_start, | 144 input_start, |
144 input_end, | 145 input_end, |
145 offsets_vector); | 146 offsets_vector, |
| 147 isolate); |
146 return res; | 148 return res; |
147 } | 149 } |
148 | 150 |
149 | 151 |
150 NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Execute( | 152 NativeRegExpMacroAssembler::Result NativeRegExpMacroAssembler::Execute( |
151 Code* code, | 153 Code* code, |
152 String* input, | 154 String* input, |
153 int start_offset, | 155 int start_offset, |
154 const byte* input_start, | 156 const byte* input_start, |
155 const byte* input_end, | 157 const byte* input_end, |
156 int* output) { | 158 int* output, |
| 159 Isolate* isolate) { |
| 160 ASSERT(isolate == Isolate::Current()); |
157 // Ensure that the minimum stack has been allocated. | 161 // Ensure that the minimum stack has been allocated. |
158 RegExpStack stack; | 162 RegExpStackScope stack_scope(isolate); |
159 Address stack_base = RegExpStack::stack_base(); | 163 Address stack_base = stack_scope.stack()->stack_base(); |
160 | 164 |
161 int direct_call = 0; | 165 int direct_call = 0; |
162 int result = CALL_GENERATED_REGEXP_CODE(code->entry(), | 166 int result = CALL_GENERATED_REGEXP_CODE(code->entry(), |
163 input, | 167 input, |
164 start_offset, | 168 start_offset, |
165 input_start, | 169 input_start, |
166 input_end, | 170 input_end, |
167 output, | 171 output, |
168 stack_base, | 172 stack_base, |
169 direct_call); | 173 direct_call, |
| 174 isolate); |
170 ASSERT(result <= SUCCESS); | 175 ASSERT(result <= SUCCESS); |
171 ASSERT(result >= RETRY); | 176 ASSERT(result >= RETRY); |
172 | 177 |
173 if (result == EXCEPTION && !Top::has_pending_exception()) { | 178 if (result == EXCEPTION && !isolate->has_pending_exception()) { |
174 // We detected a stack overflow (on the backtrack stack) in RegExp code, | 179 // We detected a stack overflow (on the backtrack stack) in RegExp code, |
175 // but haven't created the exception yet. | 180 // but haven't created the exception yet. |
176 Top::StackOverflow(); | 181 isolate->StackOverflow(); |
177 } | 182 } |
178 return static_cast<Result>(result); | 183 return static_cast<Result>(result); |
179 } | 184 } |
180 | 185 |
181 | 186 |
182 static unibrow::Mapping<unibrow::Ecma262Canonicalize> canonicalize; | 187 const byte NativeRegExpMacroAssembler::word_character_map[] = { |
183 | |
184 | |
185 byte NativeRegExpMacroAssembler::word_character_map[] = { | |
186 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, | 188 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, |
187 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, | 189 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, |
188 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, | 190 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, |
189 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, | 191 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, |
190 | 192 |
191 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, | 193 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, |
192 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, | 194 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, |
193 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // '0' - '7' | 195 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // '0' - '7' |
194 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, // '8' - '9' | 196 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, // '8' - '9' |
195 | 197 |
196 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'A' - 'G' | 198 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'A' - 'G' |
197 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'H' - 'O' | 199 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'H' - 'O' |
198 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'P' - 'W' | 200 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'P' - 'W' |
199 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, // 'X' - 'Z', '_' | 201 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0xffu, // 'X' - 'Z', '_' |
200 | 202 |
201 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'a' - 'g' | 203 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'a' - 'g' |
202 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'h' - 'o' | 204 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'h' - 'o' |
203 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'p' - 'w' | 205 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'p' - 'w' |
204 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, // 'x' - 'z' | 206 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, // 'x' - 'z' |
205 }; | 207 }; |
206 | 208 |
207 | 209 |
208 int NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16( | 210 int NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16( |
209 Address byte_offset1, | 211 Address byte_offset1, |
210 Address byte_offset2, | 212 Address byte_offset2, |
211 size_t byte_length) { | 213 size_t byte_length, |
| 214 Isolate* isolate) { |
| 215 ASSERT(isolate == Isolate::Current()); |
| 216 unibrow::Mapping<unibrow::Ecma262Canonicalize>* canonicalize = |
| 217 isolate->regexp_macro_assembler_canonicalize(); |
212 // This function is not allowed to cause a garbage collection. | 218 // This function is not allowed to cause a garbage collection. |
213 // A GC might move the calling generated code and invalidate the | 219 // A GC might move the calling generated code and invalidate the |
214 // return address on the stack. | 220 // return address on the stack. |
215 ASSERT(byte_length % 2 == 0); | 221 ASSERT(byte_length % 2 == 0); |
216 uc16* substring1 = reinterpret_cast<uc16*>(byte_offset1); | 222 uc16* substring1 = reinterpret_cast<uc16*>(byte_offset1); |
217 uc16* substring2 = reinterpret_cast<uc16*>(byte_offset2); | 223 uc16* substring2 = reinterpret_cast<uc16*>(byte_offset2); |
218 size_t length = byte_length >> 1; | 224 size_t length = byte_length >> 1; |
219 | 225 |
220 for (size_t i = 0; i < length; i++) { | 226 for (size_t i = 0; i < length; i++) { |
221 unibrow::uchar c1 = substring1[i]; | 227 unibrow::uchar c1 = substring1[i]; |
222 unibrow::uchar c2 = substring2[i]; | 228 unibrow::uchar c2 = substring2[i]; |
223 if (c1 != c2) { | 229 if (c1 != c2) { |
224 unibrow::uchar s1[1] = { c1 }; | 230 unibrow::uchar s1[1] = { c1 }; |
225 canonicalize.get(c1, '\0', s1); | 231 canonicalize->get(c1, '\0', s1); |
226 if (s1[0] != c2) { | 232 if (s1[0] != c2) { |
227 unibrow::uchar s2[1] = { c2 }; | 233 unibrow::uchar s2[1] = { c2 }; |
228 canonicalize.get(c2, '\0', s2); | 234 canonicalize->get(c2, '\0', s2); |
229 if (s1[0] != s2[0]) { | 235 if (s1[0] != s2[0]) { |
230 return 0; | 236 return 0; |
231 } | 237 } |
232 } | 238 } |
233 } | 239 } |
234 } | 240 } |
235 return 1; | 241 return 1; |
236 } | 242 } |
237 | 243 |
238 | 244 |
239 Address NativeRegExpMacroAssembler::GrowStack(Address stack_pointer, | 245 Address NativeRegExpMacroAssembler::GrowStack(Address stack_pointer, |
240 Address* stack_base) { | 246 Address* stack_base, |
241 size_t size = RegExpStack::stack_capacity(); | 247 Isolate* isolate) { |
242 Address old_stack_base = RegExpStack::stack_base(); | 248 ASSERT(isolate == Isolate::Current()); |
| 249 RegExpStack* regexp_stack = isolate->regexp_stack(); |
| 250 size_t size = regexp_stack->stack_capacity(); |
| 251 Address old_stack_base = regexp_stack->stack_base(); |
243 ASSERT(old_stack_base == *stack_base); | 252 ASSERT(old_stack_base == *stack_base); |
244 ASSERT(stack_pointer <= old_stack_base); | 253 ASSERT(stack_pointer <= old_stack_base); |
245 ASSERT(static_cast<size_t>(old_stack_base - stack_pointer) <= size); | 254 ASSERT(static_cast<size_t>(old_stack_base - stack_pointer) <= size); |
246 Address new_stack_base = RegExpStack::EnsureCapacity(size * 2); | 255 Address new_stack_base = regexp_stack->EnsureCapacity(size * 2); |
247 if (new_stack_base == NULL) { | 256 if (new_stack_base == NULL) { |
248 return NULL; | 257 return NULL; |
249 } | 258 } |
250 *stack_base = new_stack_base; | 259 *stack_base = new_stack_base; |
251 intptr_t stack_content_size = old_stack_base - stack_pointer; | 260 intptr_t stack_content_size = old_stack_base - stack_pointer; |
252 return new_stack_base - stack_content_size; | 261 return new_stack_base - stack_content_size; |
253 } | 262 } |
254 | 263 |
255 #endif // V8_INTERPRETED_REGEXP | 264 #endif // V8_INTERPRETED_REGEXP |
256 | 265 |
257 } } // namespace v8::internal | 266 } } // namespace v8::internal |
OLD | NEW |