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

Unified Diff: src/jsregexp.cc

Issue 6076: Added special case for atomic regular expressions. (Closed)
Patch Set: Created 12 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 | « src/jsregexp.h ('k') | src/log.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/jsregexp.cc
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 851700b71fa06c6595d627dd8f372121e8428a93..0e4dee19ded0d754c157bc1c1e3e23455dbd67c2 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -32,6 +32,7 @@
#include "jsregexp.h"
#include "third_party/jscre/pcre.h"
#include "platform.h"
+#include "runtime.h"
#include "top.h"
namespace v8 { namespace internal {
@@ -142,6 +143,117 @@ Handle<String> RegExpImpl::StringToTwoByte(Handle<String> pattern) {
}
+unibrow::Predicate<unibrow::RegExpSpecialChar, 128> is_reg_exp_special_char;
+
+
+Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
+ Handle<String> pattern,
+ Handle<String> flags) {
+ bool is_atom = true;
+ for (int i = 0; is_atom && i < flags->length(); i++) {
+ if (flags->Get(i) == 'i')
+ is_atom = false;
+ }
+ for (int i = 0; is_atom && i < pattern->length(); i++) {
+ if (is_reg_exp_special_char.get(pattern->Get(i)))
+ is_atom = false;
+ }
+ Handle<Object> result;
+ if (is_atom) {
+ result = AtomCompile(re, pattern);
+ } else {
+ result = JsreCompile(re, pattern, flags);
+ }
+
+ LOG(RegExpCompileEvent(re));
+ return result;
+}
+
+
+Handle<Object> RegExpImpl::Exec(Handle<JSRegExp> regexp,
+ Handle<String> subject,
+ Handle<Object> index) {
+ switch (regexp->type_tag()) {
+ case JSRegExp::JSCRE:
+ return JsreExec(regexp, subject, index);
+ case JSRegExp::ATOM:
+ return AtomExec(regexp, subject, index);
+ default:
+ UNREACHABLE();
+ return Handle<Object>();
+ }
+}
+
+
+Handle<Object> RegExpImpl::ExecGlobal(Handle<JSRegExp> regexp,
+ Handle<String> subject) {
+ switch (regexp->type_tag()) {
+ case JSRegExp::JSCRE:
+ return JsreExecGlobal(regexp, subject);
+ case JSRegExp::ATOM:
+ return AtomExecGlobal(regexp, subject);
+ default:
+ UNREACHABLE();
+ return Handle<Object>();
+ }
+}
+
+
+Handle<Object> RegExpImpl::AtomCompile(Handle<JSRegExp> re,
+ Handle<String> pattern) {
+ re->set_type_tag(JSRegExp::ATOM);
+ re->set_data(*pattern);
+ return re;
+}
+
+
+Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
+ Handle<String> subject,
+ Handle<Object> index) {
+ Handle<String> needle(String::cast(re->data()));
+
+ uint32_t start_index;
+ if (!Array::IndexFromObject(*index, &start_index)) {
+ return Handle<Smi>(Smi::FromInt(-1));
+ }
+
+ LOG(RegExpExecEvent(re, start_index, subject));
+ int value = Runtime::StringMatchKmp(*subject, *needle, start_index);
+ if (value == -1) return Factory::null_value();
+ Handle<JSArray> result = Factory::NewJSArray(2);
+ SetElement(result, 0, Handle<Smi>(Smi::FromInt(value)));
+ SetElement(result, 1, Handle<Smi>(Smi::FromInt(value + needle->length())));
+ return result;
+}
+
+
+Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re,
+ Handle<String> subject) {
+ Handle<String> needle(String::cast(re->data()));
+ Handle<JSArray> result = Factory::NewJSArray(1);
+ bool keep_going = true;
+ int index = 0;
+ int match_count = 0;
+ int needle_length = needle->length();
+ while (keep_going) {
+ LOG(RegExpExecEvent(re, index, subject));
+ int value = Runtime::StringMatchKmp(*subject, *needle, index);
+ if (value == -1) break;
+ HandleScope scope;
+ int end = value + needle_length;
+ Handle<JSArray> pair = Factory::NewJSArray(2);
+ SetElement(pair, 0, Handle<Smi>(Smi::FromInt(value)));
+ SetElement(pair, 1, Handle<Smi>(Smi::FromInt(end)));
+ SetElement(result, match_count, pair);
+ match_count++;
+ index = end;
+ if (needle_length == 0)
+ index++;
+ }
+ return result;
+}
+
+
Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
Handle<String> pattern,
Handle<String> flags) {
@@ -206,8 +318,6 @@ Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
re->set_type_tag(JSRegExp::JSCRE);
re->set_data(*value);
- LOG(RegExpCompileEvent(re));
-
return re;
}
@@ -260,7 +370,6 @@ Handle<Object> RegExpImpl::JsreExecOnce(Handle<JSRegExp> regexp,
SetElement(result, i, Handle<Object>(Smi::FromInt(offsets_vector[i])));
SetElement(result, i+1, Handle<Object>(Smi::FromInt(offsets_vector[i+1])));
}
-
return result;
}
« no previous file with comments | « src/jsregexp.h ('k') | src/log.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698