| Index: regexp2000/src/jsregexp.cc
|
| diff --git a/regexp2000/src/jsregexp.cc b/regexp2000/src/jsregexp.cc
|
| index 30e4d7f813800adb01c04b7567f1f2c4fbe3095f..5f3df57f3980a91d698c372e2b0ceb787f74fee5 100644
|
| --- a/regexp2000/src/jsregexp.cc
|
| +++ b/regexp2000/src/jsregexp.cc
|
| @@ -39,7 +39,7 @@
|
| #include "top.h"
|
| #include "compilation-cache.h"
|
| #include "string-stream.h"
|
| -
|
| +#include "parser.h"
|
|
|
| namespace v8 { namespace internal {
|
|
|
| @@ -168,9 +168,20 @@ static JSRegExp::Flags RegExpFlagsFromString(Handle<String> str) {
|
| }
|
|
|
|
|
| -unibrow::Predicate<unibrow::RegExpSpecialChar, 128> is_reg_exp_special_char;
|
| +static inline Handle<Object> CreateRegExpException(Handle<JSRegExp> re,
|
| + Handle<String> pattern,
|
| + Handle<String> error_text,
|
| + const char* message) {
|
| + Handle<JSArray> array = Factory::NewJSArray(2);
|
| + SetElement(array, 0, pattern);
|
| + SetElement(array, 1, error_text);
|
| + Handle<Object> regexp_err = Factory::NewSyntaxError(message, array);
|
| + return Handle<Object>(Top::Throw(*regexp_err));
|
| +}
|
|
|
|
|
| +unibrow::Predicate<unibrow::RegExpSpecialChar, 128> is_reg_exp_special_char;
|
| +
|
| Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
|
| Handle<String> pattern,
|
| Handle<String> flag_str) {
|
| @@ -182,13 +193,20 @@ Handle<Object> RegExpImpl::Compile(Handle<JSRegExp> re,
|
| re->set_data(*cached);
|
| result = re;
|
| } else {
|
| - bool is_atom = !flags.is_ignore_case();
|
| - for (int i = 0; is_atom && i < pattern->length(); i++) {
|
| - if (is_reg_exp_special_char.get(pattern->Get(i)))
|
| - is_atom = false;
|
| + SafeStringInputBuffer buffer(pattern.location());
|
| + Handle<String> error_text;
|
| + RegExpTree* ast = ParseRegExp(&buffer, &error_text);
|
| + if (!error_text.is_null()) {
|
| + // Throw an exception if we fail to parse the pattern.
|
| + return CreateRegExpException(re, pattern, error_text, "malformed_regexp");
|
| }
|
| - if (is_atom) {
|
| - result = AtomCompile(re, pattern, flags);
|
| +
|
| + RegExpAtom* atom = ast->AsAtom();
|
| + if (atom != NULL && !flags.is_ignore_case()) {
|
| + Vector<const uc16> atom_pattern = atom->data();
|
| + // Test if pattern equals atom_pattern and reuse pattern if it does.
|
| + Handle<String> atom_string = Factory::NewStringFromTwoByte(atom_pattern);
|
| + result = AtomCompile(re, atom_string, flags);
|
| } else {
|
| result = JsreCompile(re, pattern, flags);
|
| }
|
| @@ -238,6 +256,7 @@ Handle<Object> RegExpImpl::ExecGlobal(Handle<JSRegExp> regexp,
|
| Handle<Object> RegExpImpl::AtomCompile(Handle<JSRegExp> re,
|
| Handle<String> pattern,
|
| JSRegExp::Flags flags) {
|
| + ASSERT(!flags.is_ignore_case());
|
| Factory::SetRegExpData(re, JSRegExp::ATOM, pattern, flags, pattern);
|
| return re;
|
| }
|
| @@ -306,6 +325,8 @@ Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re,
|
| Handle<Object> RegExpImpl::JsreCompile(Handle<JSRegExp> re,
|
| Handle<String> pattern,
|
| JSRegExp::Flags flags) {
|
| + // Change this to not compile immediately, but defer the compilation
|
| + // until the first execution.
|
| JSRegExpIgnoreCaseOption case_option = flags.is_ignore_case()
|
| ? JSRegExpIgnoreCase
|
| : JSRegExpDoNotIgnoreCase;
|
|
|