| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 Handle<String> two_byte_string = StringToTwoByte(subject); | 122 Handle<String> two_byte_string = StringToTwoByte(subject); |
| 123 last_ascii_string_ = *subject; | 123 last_ascii_string_ = *subject; |
| 124 two_byte_cached_string_ = *two_byte_string; | 124 two_byte_cached_string_ = *two_byte_string; |
| 125 return two_byte_string; | 125 return two_byte_string; |
| 126 } | 126 } |
| 127 | 127 |
| 128 | 128 |
| 129 // Converts a source string to a 16 bit flat string or a SlicedString containing | 129 // Converts a source string to a 16 bit flat string or a SlicedString containing |
| 130 // a 16 bit flat string). | 130 // a 16 bit flat string). |
| 131 Handle<String> RegExpImpl::StringToTwoByte(Handle<String> pattern) { | 131 Handle<String> RegExpImpl::StringToTwoByte(Handle<String> pattern) { |
| 132 if (!pattern->IsFlat()) { | 132 StringShape shape(*pattern); |
| 133 if (!pattern->IsFlat(shape)) { |
| 133 FlattenString(pattern); | 134 FlattenString(pattern); |
| 134 } | 135 } |
| 135 Handle<String> flat_string(pattern->IsConsString() ? | 136 Handle<String> flat_string(shape.IsCons() ? |
| 136 String::cast(ConsString::cast(*pattern)->first()) : | 137 String::cast(ConsString::cast(*pattern)->first()) : |
| 137 *pattern); | 138 *pattern); |
| 138 ASSERT(!flat_string->IsConsString()); | 139 ASSERT(flat_string->IsString()); |
| 139 ASSERT(flat_string->IsSeqString() || flat_string->IsSlicedString() || | 140 StringShape flat_shape(*flat_string); |
| 140 flat_string->IsExternalString()); | 141 ASSERT(!flat_shape.IsCons()); |
| 141 if (!flat_string->IsAsciiRepresentation()) { | 142 ASSERT(flat_shape.IsSequential() || |
| 143 flat_shape.IsSliced() || |
| 144 flat_shape.IsExternal()); |
| 145 if (!flat_shape.IsAsciiRepresentation()) { |
| 142 return flat_string; | 146 return flat_string; |
| 143 } | 147 } |
| 144 | 148 |
| 149 int len = flat_string->length(flat_shape); |
| 145 Handle<String> two_byte_string = | 150 Handle<String> two_byte_string = |
| 146 Factory::NewRawTwoByteString(flat_string->length(), TENURED); | 151 Factory::NewRawTwoByteString(len, TENURED); |
| 147 static StringInputBuffer convert_to_two_byte_buffer; | 152 uc16* dest = SeqTwoByteString::cast(*two_byte_string)->GetChars(); |
| 148 convert_to_two_byte_buffer.Reset(*flat_string); | 153 String::WriteToFlat(*flat_string, flat_shape, dest, 0, len); |
| 149 for (int i = 0; convert_to_two_byte_buffer.has_more(); i++) { | |
| 150 two_byte_string->Set(i, convert_to_two_byte_buffer.GetNext()); | |
| 151 } | |
| 152 return two_byte_string; | 154 return two_byte_string; |
| 153 } | 155 } |
| 154 | 156 |
| 155 | 157 |
| 156 static JSRegExp::Flags RegExpFlagsFromString(Handle<String> str) { | 158 static JSRegExp::Flags RegExpFlagsFromString(Handle<String> str) { |
| 157 int flags = JSRegExp::NONE; | 159 int flags = JSRegExp::NONE; |
| 158 for (int i = 0; i < str->length(); i++) { | 160 StringShape shape(*str); |
| 159 switch (str->Get(i)) { | 161 for (int i = 0; i < str->length(shape); i++) { |
| 162 switch (str->Get(shape, i)) { |
| 160 case 'i': | 163 case 'i': |
| 161 flags |= JSRegExp::IGNORE_CASE; | 164 flags |= JSRegExp::IGNORE_CASE; |
| 162 break; | 165 break; |
| 163 case 'g': | 166 case 'g': |
| 164 flags |= JSRegExp::GLOBAL; | 167 flags |= JSRegExp::GLOBAL; |
| 165 break; | 168 break; |
| 166 case 'm': | 169 case 'm': |
| 167 flags |= JSRegExp::MULTILINE; | 170 flags |= JSRegExp::MULTILINE; |
| 168 break; | 171 break; |
| 169 } | 172 } |
| 170 } | 173 } |
| 171 return JSRegExp::Flags(flags); | 174 return JSRegExp::Flags(flags); |
| 172 } | 175 } |
| 173 | 176 |
| 174 | 177 |
| 175 unibrow::Predicate<unibrow::RegExpSpecialChar, 128> is_reg_exp_special_char; | 178 unibrow::Predicate<unibrow::RegExpSpecialChar, 128> is_reg_exp_special_char; |
| 176 | 179 |
| 177 | 180 |
| 178 Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re, | 181 Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re, |
| 179 Handle<String> pattern, | 182 Handle<String> pattern, |
| 180 Handle<String> flag_str) { | 183 Handle<String> flag_str) { |
| 181 JSRegExp::Flags flags = RegExpFlagsFromString(flag_str); | 184 JSRegExp::Flags flags = RegExpFlagsFromString(flag_str); |
| 182 Handle<FixedArray> cached = CompilationCache::LookupRegExp(pattern, flags); | 185 Handle<FixedArray> cached = CompilationCache::LookupRegExp(pattern, flags); |
| 183 bool in_cache = !cached.is_null(); | 186 bool in_cache = !cached.is_null(); |
| 184 Handle<Object> result; | 187 Handle<Object> result; |
| 188 StringShape shape(*pattern); |
| 185 if (in_cache) { | 189 if (in_cache) { |
| 186 re->set_data(*cached); | 190 re->set_data(*cached); |
| 187 result = re; | 191 result = re; |
| 188 } else { | 192 } else { |
| 189 bool is_atom = !flags.is_ignore_case(); | 193 bool is_atom = !flags.is_ignore_case(); |
| 190 for (int i = 0; is_atom && i < pattern->length(); i++) { | 194 for (int i = 0; is_atom && i < pattern->length(shape); i++) { |
| 191 if (is_reg_exp_special_char.get(pattern->Get(i))) | 195 if (is_reg_exp_special_char.get(pattern->Get(shape, i))) |
| 192 is_atom = false; | 196 is_atom = false; |
| 193 } | 197 } |
| 194 if (is_atom) { | 198 if (is_atom) { |
| 195 result = AtomCompile(re, pattern, flags); | 199 result = AtomCompile(re, pattern, flags); |
| 196 } else { | 200 } else { |
| 197 result = JsreCompile(re, pattern, flags); | 201 result = JsreCompile(re, pattern, flags); |
| 198 } | 202 } |
| 199 Object* data = re->data(); | 203 Object* data = re->data(); |
| 200 if (data->IsFixedArray()) { | 204 if (data->IsFixedArray()) { |
| 201 // If compilation succeeded then the data is set on the regexp | 205 // If compilation succeeded then the data is set on the regexp |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 return Smi::cast(value->get(CAPTURE_INDEX))->value(); | 565 return Smi::cast(value->get(CAPTURE_INDEX))->value(); |
| 562 } | 566 } |
| 563 | 567 |
| 564 | 568 |
| 565 ByteArray* RegExpImpl::JsreInternal(Handle<JSRegExp> re) { | 569 ByteArray* RegExpImpl::JsreInternal(Handle<JSRegExp> re) { |
| 566 FixedArray* value = FixedArray::cast(re->DataAt(JSRegExp::kJscreDataIndex)); | 570 FixedArray* value = FixedArray::cast(re->DataAt(JSRegExp::kJscreDataIndex)); |
| 567 return ByteArray::cast(value->get(INTERNAL_INDEX)); | 571 return ByteArray::cast(value->get(INTERNAL_INDEX)); |
| 568 } | 572 } |
| 569 | 573 |
| 570 }} // namespace v8::internal | 574 }} // namespace v8::internal |
| OLD | NEW |