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 |