| 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, |
| 157 Isolate* isolate = Isolate::Current(); | 159 Isolate* isolate) { |
| 160 ASSERT(isolate == Isolate::Current()); |
| 158 typedef int (*matcher)(String*, int, const byte*, | 161 typedef int (*matcher)(String*, int, const byte*, |
| 159 const byte*, int*, Address, int); | 162 const byte*, int*, Address, int, Isolate*); |
| 160 matcher matcher_func = FUNCTION_CAST<matcher>(code->entry()); | 163 matcher matcher_func = FUNCTION_CAST<matcher>(code->entry()); |
| 161 | 164 |
| 162 // Ensure that the minimum stack has been allocated. | 165 // Ensure that the minimum stack has been allocated. |
| 163 RegExpStackScope stack_scope(isolate); | 166 RegExpStackScope stack_scope(isolate); |
| 164 Address stack_base = stack_scope.stack()->stack_base(); | 167 Address stack_base = stack_scope.stack()->stack_base(); |
| 165 | 168 |
| 166 int direct_call = 0; | 169 int direct_call = 0; |
| 167 int result = CALL_GENERATED_REGEXP_CODE(matcher_func, | 170 int result = CALL_GENERATED_REGEXP_CODE(matcher_func, |
| 168 input, | 171 input, |
| 169 start_offset, | 172 start_offset, |
| 170 input_start, | 173 input_start, |
| 171 input_end, | 174 input_end, |
| 172 output, | 175 output, |
| 173 stack_base, | 176 stack_base, |
| 174 direct_call); | 177 direct_call, |
| 178 isolate); |
| 175 ASSERT(result <= SUCCESS); | 179 ASSERT(result <= SUCCESS); |
| 176 ASSERT(result >= RETRY); | 180 ASSERT(result >= RETRY); |
| 177 | 181 |
| 178 if (result == EXCEPTION && !isolate->has_pending_exception()) { | 182 if (result == EXCEPTION && !isolate->has_pending_exception()) { |
| 179 // We detected a stack overflow (on the backtrack stack) in RegExp code, | 183 // We detected a stack overflow (on the backtrack stack) in RegExp code, |
| 180 // but haven't created the exception yet. | 184 // but haven't created the exception yet. |
| 181 isolate->StackOverflow(); | 185 isolate->StackOverflow(); |
| 182 } | 186 } |
| 183 return static_cast<Result>(result); | 187 return static_cast<Result>(result); |
| 184 } | 188 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 203 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'a' - 'g' | 207 0x00u, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'a' - 'g' |
| 204 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'h' - 'o' | 208 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'h' - 'o' |
| 205 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'p' - 'w' | 209 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, 0xffu, // 'p' - 'w' |
| 206 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, // 'x' - 'z' | 210 0xffu, 0xffu, 0xffu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, // 'x' - 'z' |
| 207 }; | 211 }; |
| 208 | 212 |
| 209 | 213 |
| 210 int NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16( | 214 int NativeRegExpMacroAssembler::CaseInsensitiveCompareUC16( |
| 211 Address byte_offset1, | 215 Address byte_offset1, |
| 212 Address byte_offset2, | 216 Address byte_offset2, |
| 213 size_t byte_length) { | 217 size_t byte_length, |
| 218 Isolate* isolate) { |
| 219 ASSERT(isolate == Isolate::Current()); |
| 214 unibrow::Mapping<unibrow::Ecma262Canonicalize>* canonicalize = | 220 unibrow::Mapping<unibrow::Ecma262Canonicalize>* canonicalize = |
| 215 Isolate::Current()->regexp_macro_assembler_canonicalize(); | 221 isolate->regexp_macro_assembler_canonicalize(); |
| 216 // This function is not allowed to cause a garbage collection. | 222 // This function is not allowed to cause a garbage collection. |
| 217 // A GC might move the calling generated code and invalidate the | 223 // A GC might move the calling generated code and invalidate the |
| 218 // return address on the stack. | 224 // return address on the stack. |
| 219 ASSERT(byte_length % 2 == 0); | 225 ASSERT(byte_length % 2 == 0); |
| 220 uc16* substring1 = reinterpret_cast<uc16*>(byte_offset1); | 226 uc16* substring1 = reinterpret_cast<uc16*>(byte_offset1); |
| 221 uc16* substring2 = reinterpret_cast<uc16*>(byte_offset2); | 227 uc16* substring2 = reinterpret_cast<uc16*>(byte_offset2); |
| 222 size_t length = byte_length >> 1; | 228 size_t length = byte_length >> 1; |
| 223 | 229 |
| 224 for (size_t i = 0; i < length; i++) { | 230 for (size_t i = 0; i < length; i++) { |
| 225 unibrow::uchar c1 = substring1[i]; | 231 unibrow::uchar c1 = substring1[i]; |
| 226 unibrow::uchar c2 = substring2[i]; | 232 unibrow::uchar c2 = substring2[i]; |
| 227 if (c1 != c2) { | 233 if (c1 != c2) { |
| 228 unibrow::uchar s1[1] = { c1 }; | 234 unibrow::uchar s1[1] = { c1 }; |
| 229 canonicalize->get(c1, '\0', s1); | 235 canonicalize->get(c1, '\0', s1); |
| 230 if (s1[0] != c2) { | 236 if (s1[0] != c2) { |
| 231 unibrow::uchar s2[1] = { c2 }; | 237 unibrow::uchar s2[1] = { c2 }; |
| 232 canonicalize->get(c2, '\0', s2); | 238 canonicalize->get(c2, '\0', s2); |
| 233 if (s1[0] != s2[0]) { | 239 if (s1[0] != s2[0]) { |
| 234 return 0; | 240 return 0; |
| 235 } | 241 } |
| 236 } | 242 } |
| 237 } | 243 } |
| 238 } | 244 } |
| 239 return 1; | 245 return 1; |
| 240 } | 246 } |
| 241 | 247 |
| 242 | 248 |
| 243 Address NativeRegExpMacroAssembler::GrowStack(Address stack_pointer, | 249 Address NativeRegExpMacroAssembler::GrowStack(Address stack_pointer, |
| 244 Address* stack_base) { | 250 Address* stack_base, |
| 245 RegExpStack* regexp_stack = Isolate::Current()->regexp_stack(); | 251 Isolate* isolate) { |
| 252 ASSERT(isolate == Isolate::Current()); |
| 253 RegExpStack* regexp_stack = isolate->regexp_stack(); |
| 246 size_t size = regexp_stack->stack_capacity(); | 254 size_t size = regexp_stack->stack_capacity(); |
| 247 Address old_stack_base = regexp_stack->stack_base(); | 255 Address old_stack_base = regexp_stack->stack_base(); |
| 248 ASSERT(old_stack_base == *stack_base); | 256 ASSERT(old_stack_base == *stack_base); |
| 249 ASSERT(stack_pointer <= old_stack_base); | 257 ASSERT(stack_pointer <= old_stack_base); |
| 250 ASSERT(static_cast<size_t>(old_stack_base - stack_pointer) <= size); | 258 ASSERT(static_cast<size_t>(old_stack_base - stack_pointer) <= size); |
| 251 Address new_stack_base = regexp_stack->EnsureCapacity(size * 2); | 259 Address new_stack_base = regexp_stack->EnsureCapacity(size * 2); |
| 252 if (new_stack_base == NULL) { | 260 if (new_stack_base == NULL) { |
| 253 return NULL; | 261 return NULL; |
| 254 } | 262 } |
| 255 *stack_base = new_stack_base; | 263 *stack_base = new_stack_base; |
| 256 intptr_t stack_content_size = old_stack_base - stack_pointer; | 264 intptr_t stack_content_size = old_stack_base - stack_pointer; |
| 257 return new_stack_base - stack_content_size; | 265 return new_stack_base - stack_content_size; |
| 258 } | 266 } |
| 259 | 267 |
| 260 #endif // V8_INTERPRETED_REGEXP | 268 #endif // V8_INTERPRETED_REGEXP |
| 261 | 269 |
| 262 } } // namespace v8::internal | 270 } } // namespace v8::internal |
| OLD | NEW |