OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 break; | 88 break; |
89 case 'm': | 89 case 'm': |
90 flags |= JSRegExp::MULTILINE; | 90 flags |= JSRegExp::MULTILINE; |
91 break; | 91 break; |
92 } | 92 } |
93 } | 93 } |
94 return JSRegExp::Flags(flags); | 94 return JSRegExp::Flags(flags); |
95 } | 95 } |
96 | 96 |
97 | 97 |
98 static inline void ThrowRegExpException(Handle<JSRegExp> re, | 98 MUST_USE_RESULT |
99 Handle<String> pattern, | 99 static inline MaybeHandle<Object> ThrowRegExpException( |
100 Handle<String> error_text, | 100 Handle<JSRegExp> re, |
101 const char* message) { | 101 Handle<String> pattern, |
| 102 Handle<String> error_text, |
| 103 const char* message) { |
102 Isolate* isolate = re->GetIsolate(); | 104 Isolate* isolate = re->GetIsolate(); |
103 Factory* factory = isolate->factory(); | 105 Factory* factory = isolate->factory(); |
104 Handle<FixedArray> elements = factory->NewFixedArray(2); | 106 Handle<FixedArray> elements = factory->NewFixedArray(2); |
105 elements->set(0, *pattern); | 107 elements->set(0, *pattern); |
106 elements->set(1, *error_text); | 108 elements->set(1, *error_text); |
107 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 109 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
108 Handle<Object> regexp_err = factory->NewSyntaxError(message, array); | 110 Handle<Object> regexp_err = factory->NewSyntaxError(message, array); |
109 isolate->Throw(*regexp_err); | 111 return isolate->Throw<Object>(regexp_err); |
110 } | 112 } |
111 | 113 |
112 | 114 |
113 ContainedInLattice AddRange(ContainedInLattice containment, | 115 ContainedInLattice AddRange(ContainedInLattice containment, |
114 const int* ranges, | 116 const int* ranges, |
115 int ranges_length, | 117 int ranges_length, |
116 Interval new_range) { | 118 Interval new_range) { |
117 ASSERT((ranges_length & 1) == 1); | 119 ASSERT((ranges_length & 1) == 1); |
118 ASSERT(ranges[ranges_length - 1] == String::kMaxUtf16CodeUnit + 1); | 120 ASSERT(ranges[ranges_length - 1] == String::kMaxUtf16CodeUnit + 1); |
119 if (containment == kLatticeUnknown) return containment; | 121 if (containment == kLatticeUnknown) return containment; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 if (different * 3 > length) return false; | 162 if (different * 3 > length) return false; |
161 } | 163 } |
162 } | 164 } |
163 return true; | 165 return true; |
164 } | 166 } |
165 | 167 |
166 | 168 |
167 // Generic RegExp methods. Dispatches to implementation specific methods. | 169 // Generic RegExp methods. Dispatches to implementation specific methods. |
168 | 170 |
169 | 171 |
170 Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re, | 172 MaybeHandle<Object> RegExpImpl::Compile(Handle<JSRegExp> re, |
171 Handle<String> pattern, | 173 Handle<String> pattern, |
172 Handle<String> flag_str) { | 174 Handle<String> flag_str) { |
173 Isolate* isolate = re->GetIsolate(); | 175 Isolate* isolate = re->GetIsolate(); |
174 Zone zone(isolate); | 176 Zone zone(isolate); |
175 JSRegExp::Flags flags = RegExpFlagsFromString(flag_str); | 177 JSRegExp::Flags flags = RegExpFlagsFromString(flag_str); |
176 CompilationCache* compilation_cache = isolate->compilation_cache(); | 178 CompilationCache* compilation_cache = isolate->compilation_cache(); |
177 MaybeHandle<FixedArray> maybe_cached = | 179 MaybeHandle<FixedArray> maybe_cached = |
178 compilation_cache->LookupRegExp(pattern, flags); | 180 compilation_cache->LookupRegExp(pattern, flags); |
179 Handle<FixedArray> cached; | 181 Handle<FixedArray> cached; |
180 bool in_cache = maybe_cached.ToHandle(&cached); | 182 bool in_cache = maybe_cached.ToHandle(&cached); |
181 LOG(isolate, RegExpCompileEvent(re, in_cache)); | 183 LOG(isolate, RegExpCompileEvent(re, in_cache)); |
182 | 184 |
183 Handle<Object> result; | 185 Handle<Object> result; |
184 if (in_cache) { | 186 if (in_cache) { |
185 re->set_data(*cached); | 187 re->set_data(*cached); |
186 return re; | 188 return re; |
187 } | 189 } |
188 pattern = String::Flatten(pattern); | 190 pattern = String::Flatten(pattern); |
189 PostponeInterruptsScope postpone(isolate); | 191 PostponeInterruptsScope postpone(isolate); |
190 RegExpCompileData parse_result; | 192 RegExpCompileData parse_result; |
191 FlatStringReader reader(isolate, pattern); | 193 FlatStringReader reader(isolate, pattern); |
192 if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(), | 194 if (!RegExpParser::ParseRegExp(&reader, flags.is_multiline(), |
193 &parse_result, &zone)) { | 195 &parse_result, &zone)) { |
194 // Throw an exception if we fail to parse the pattern. | 196 // Throw an exception if we fail to parse the pattern. |
195 ThrowRegExpException(re, | 197 return ThrowRegExpException(re, |
196 pattern, | 198 pattern, |
197 parse_result.error, | 199 parse_result.error, |
198 "malformed_regexp"); | 200 "malformed_regexp"); |
199 return Handle<Object>::null(); | |
200 } | 201 } |
201 | 202 |
202 bool has_been_compiled = false; | 203 bool has_been_compiled = false; |
203 | 204 |
204 if (parse_result.simple && | 205 if (parse_result.simple && |
205 !flags.is_ignore_case() && | 206 !flags.is_ignore_case() && |
206 !HasFewDifferentCharacters(pattern)) { | 207 !HasFewDifferentCharacters(pattern)) { |
207 // Parse-tree is a single atom that is equal to the pattern. | 208 // Parse-tree is a single atom that is equal to the pattern. |
208 AtomCompile(re, pattern, flags, pattern); | 209 AtomCompile(re, pattern, flags, pattern); |
209 has_been_compiled = true; | 210 has_been_compiled = true; |
210 } else if (parse_result.tree->IsAtom() && | 211 } else if (parse_result.tree->IsAtom() && |
211 !flags.is_ignore_case() && | 212 !flags.is_ignore_case() && |
212 parse_result.capture_count == 0) { | 213 parse_result.capture_count == 0) { |
213 RegExpAtom* atom = parse_result.tree->AsAtom(); | 214 RegExpAtom* atom = parse_result.tree->AsAtom(); |
214 Vector<const uc16> atom_pattern = atom->data(); | 215 Vector<const uc16> atom_pattern = atom->data(); |
215 Handle<String> atom_string = | 216 Handle<String> atom_string; |
216 isolate->factory()->NewStringFromTwoByte(atom_pattern); | 217 ASSIGN_RETURN_ON_EXCEPTION( |
| 218 isolate, atom_string, |
| 219 isolate->factory()->NewStringFromTwoByte(atom_pattern), |
| 220 Object); |
217 if (!HasFewDifferentCharacters(atom_string)) { | 221 if (!HasFewDifferentCharacters(atom_string)) { |
218 AtomCompile(re, pattern, flags, atom_string); | 222 AtomCompile(re, pattern, flags, atom_string); |
219 has_been_compiled = true; | 223 has_been_compiled = true; |
220 } | 224 } |
221 } | 225 } |
222 if (!has_been_compiled) { | 226 if (!has_been_compiled) { |
223 IrregexpInitialize(re, pattern, flags, parse_result.capture_count); | 227 IrregexpInitialize(re, pattern, flags, parse_result.capture_count); |
224 } | 228 } |
225 ASSERT(re->data()->IsFixedArray()); | 229 ASSERT(re->data()->IsFixedArray()); |
226 // Compilation succeeded so the data is set on the regexp | 230 // Compilation succeeded so the data is set on the regexp |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 RegExpEngine::Compile(&compile_data, | 462 RegExpEngine::Compile(&compile_data, |
459 flags.is_ignore_case(), | 463 flags.is_ignore_case(), |
460 flags.is_global(), | 464 flags.is_global(), |
461 flags.is_multiline(), | 465 flags.is_multiline(), |
462 pattern, | 466 pattern, |
463 sample_subject, | 467 sample_subject, |
464 is_ascii, | 468 is_ascii, |
465 &zone); | 469 &zone); |
466 if (result.error_message != NULL) { | 470 if (result.error_message != NULL) { |
467 // Unable to compile regexp. | 471 // Unable to compile regexp. |
468 Handle<String> error_message = | 472 Handle<String> error_message = isolate->factory()->NewStringFromUtf8( |
469 isolate->factory()->NewStringFromUtf8(CStrVector(result.error_message)); | 473 CStrVector(result.error_message)).ToHandleChecked(); |
470 ASSERT(!error_message.is_null()); | |
471 CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate); | 474 CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate); |
472 return false; | 475 return false; |
473 } | 476 } |
474 | 477 |
475 Handle<FixedArray> data = Handle<FixedArray>(FixedArray::cast(re->data())); | 478 Handle<FixedArray> data = Handle<FixedArray>(FixedArray::cast(re->data())); |
476 data->set(JSRegExp::code_index(is_ascii), result.code); | 479 data->set(JSRegExp::code_index(is_ascii), result.code); |
477 int register_max = IrregexpMaxRegisterCount(*data); | 480 int register_max = IrregexpMaxRegisterCount(*data); |
478 if (result.num_registers > register_max) { | 481 if (result.num_registers > register_max) { |
479 SetIrregexpMaxRegisterCount(*data, result.num_registers); | 482 SetIrregexpMaxRegisterCount(*data, result.num_registers); |
480 } | 483 } |
(...skipping 5645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6126 } | 6129 } |
6127 | 6130 |
6128 return compiler.Assemble(¯o_assembler, | 6131 return compiler.Assemble(¯o_assembler, |
6129 node, | 6132 node, |
6130 data->capture_count, | 6133 data->capture_count, |
6131 pattern); | 6134 pattern); |
6132 } | 6135 } |
6133 | 6136 |
6134 | 6137 |
6135 }} // namespace v8::internal | 6138 }} // namespace v8::internal |
OLD | NEW |