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