Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1614)

Unified Diff: runtime/lib/regexp.cc

Issue 539153002: Port and integrate the irregexp engine from V8 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/lib/regexp_patch.dart » ('j') | runtime/vm/object.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/lib/regexp.cc
diff --git a/runtime/lib/regexp.cc b/runtime/lib/regexp.cc
index 646261628738d6904f277787168a02655548bfbd..d162d44a70eb45d071350f1088c44576af6aaee5 100644
--- a/runtime/lib/regexp.cc
+++ b/runtime/lib/regexp.cc
@@ -13,6 +13,10 @@
namespace dart {
+DECLARE_FLAG(bool, trace_irregexp);
+DEFINE_FLAG(bool, use_jscre, false,
+ "Use JSCRE instead of the irregexp engine.");
+
DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_factory, 4) {
ASSERT(TypeArguments::CheckedHandle(arguments->NativeArgAt(0)).IsNull());
GET_NON_NULL_NATIVE_ARGUMENT(String, pattern, arguments->NativeArgAt(1));
@@ -22,7 +26,22 @@ DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_factory, 4) {
Instance, handle_case_sensitive, arguments->NativeArgAt(3));
bool ignore_case = handle_case_sensitive.raw() != Bool::True().raw();
bool multi_line = handle_multi_line.raw() == Bool::True().raw();
- return Jscre::Compile(pattern, multi_line, ignore_case);
+
+ if (FLAG_use_jscre) {
+ return Jscre::Compile(pattern, multi_line, ignore_case);
+ } else {
+ // Parse the pattern once in order to throw any format exceptions within
+ // the factory constructor. It is parsed again upon compilation.
+ RegExpCompileData compileData;
+ if (!RegExpParser::ParseRegExp(pattern, multi_line, &compileData)) {
+ // Parsing failures throw an exception.
+ UNREACHABLE();
+ }
+
+ // Create a JSRegExp object containing only the initial parameters.
+ // Compilation is done upon regexp execution.
+ return RegExpEngine::New(pattern, multi_line, ignore_case);
+ }
}
@@ -65,30 +84,90 @@ DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_getGroupCount, 1) {
DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_ExecuteMatch, 3) {
- const JSRegExp& regexp = JSRegExp::CheckedHandle(arguments->NativeArgAt(0));
+ JSRegExp& regexp = JSRegExp::CheckedHandle(arguments->NativeArgAt(0));
ASSERT(!regexp.IsNull());
GET_NON_NULL_NATIVE_ARGUMENT(String, str, arguments->NativeArgAt(1));
GET_NON_NULL_NATIVE_ARGUMENT(Smi, start_index, arguments->NativeArgAt(2));
- // The irregexp parser runs alongside the jscre parser while the port is
- // still in progress. When done, it will replace jscre completely.
- const String& pattern = String::Handle(regexp.pattern());
- RegExpCompileData compileData;
- if (RegExpParser::ParseRegExp(pattern, regexp.is_multi_line(),
- &compileData)) {
- RegExpEngine::Compile(&compileData,
- regexp.is_ignore_case(),
- regexp.is_global(), // A Dart regexp is always global
- regexp.is_multi_line(),
- pattern,
- str,
- str.IsOneByteString());
- RegExpEngine::DotPrint(pattern.ToCString(),
- compileData.node,
- regexp.is_ignore_case());
+ if (FLAG_use_jscre) {
+ return Jscre::Execute(regexp, str, start_index.Value());
+ } else {
+ const bool is_one_byte_string = str.IsOneByteString();
Florian Schneider 2014/09/16 11:11:48 Could be also ExternalOneByteString.
jgruber1 2014/09/22 18:58:03 The generated code is now specialized for all four
+
+ // Retrieve the cached function.
+ Function& fn = Function::Handle(is_one_byte_string ?
+ regexp.one_byte_function() : regexp.two_byte_function());
+
+ // Compile if needed.
+ if (fn.IsNull()) {
+ // Parse the pattern.
+ const String& pattern = String::Handle(regexp.pattern());
+ RegExpCompileData compileData;
+ if (!RegExpParser::ParseRegExp(pattern, regexp.is_multi_line(),
+ &compileData)) {
+ // Parsing failures are handled in the factory constructor.
+ UNREACHABLE();
+ }
+
+ // Compile it.
+ RegExpEngine::CompilationResult result =
+ RegExpEngine::Compile(
+ &compileData,
+ regexp.is_ignore_case(),
+ regexp.is_global(), // A Dart regexp is always global
+ regexp.is_multi_line(),
+ pattern,
+ str,
+ str.IsOneByteString());
+ if (result.function.IsNull()) {
+ // Should never fail.
+ UNREACHABLE();
+ }
+
+ // Debug output of the generated state machine.
+ if (FLAG_trace_irregexp) {
+#ifdef DEBUG
+ RegExpEngine::DotPrint(pattern.ToCString(),
+ compileData.node,
+ regexp.is_ignore_case());
+#endif
+ }
+
+ // Cache the result.
+ if (is_one_byte_string) {
+ regexp.set_one_byte_function(result.function);
+ } else {
+ regexp.set_two_byte_function(result.function);
+ }
+ regexp.set_num_bracket_expressions(compileData.capture_count);
+
+ fn = result.function.raw();
+ }
+
+ ASSERT(!fn.IsNull());
+
+ // Create the output array.
Florian Schneider 2014/09/16 11:11:47 Creating the output array should be part of the ge
jgruber1 2014/09/22 18:58:03 Done.
+ const Smi& num_bracket_exprs =
+ Smi::Handle(regexp.num_bracket_expressions());
+ intptr_t num_bracket_expressions = num_bracket_exprs.Value();
+ const intptr_t kMatchPair = 2;
+ Array& matches = Array::Handle(
+ Array::New(kMatchPair * (num_bracket_expressions + 1)));
+
+ // And finally call the generated code.
+ IRRegExpMacroAssembler::Result result =
+ IRRegExpMacroAssembler::Execute(fn, str, start_index,
+ &matches, isolate);
+
+ if (result == IRRegExpMacroAssembler::SUCCESS) {
+ return matches.raw();
+ } else {
+ return Array::null();
+ }
}
- return Jscre::Execute(regexp, str, start_index.Value());
+ UNREACHABLE();
+ return Array::null();
}
} // namespace dart
« no previous file with comments | « no previous file | runtime/lib/regexp_patch.dart » ('j') | runtime/vm/object.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698