| 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 |