| Index: src/jsregexp.cc
|
| ===================================================================
|
| --- src/jsregexp.cc (revision 8501)
|
| +++ src/jsregexp.cc (working copy)
|
| @@ -295,23 +295,62 @@
|
| #else // V8_INTERPRETED_REGEXP (RegExp native code)
|
| if (compiled_code->IsCode()) return true;
|
| #endif
|
| + // We could potentially have marked this as flushable, but have kept
|
| + // a saved version if we did not flush it yet.
|
| + Object* saved_code = re->DataAt(JSRegExp::saved_code_index(is_ascii));
|
| + if (saved_code->IsCode()) {
|
| + // Reinstate the code in the original place.
|
| + re->SetDataAt(JSRegExp::code_index(is_ascii), saved_code);
|
| + ASSERT(compiled_code->IsSmi());
|
| + return true;
|
| + }
|
| return CompileIrregexp(re, is_ascii);
|
| }
|
|
|
|
|
| +static bool CreateRegExpErrorObjectAndThrow(Handle<JSRegExp> re,
|
| + bool is_ascii,
|
| + Handle<String> error_message,
|
| + Isolate* isolate) {
|
| + Factory* factory = isolate->factory();
|
| + Handle<FixedArray> elements = factory->NewFixedArray(2);
|
| + elements->set(0, re->Pattern());
|
| + elements->set(1, *error_message);
|
| + Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
|
| + Handle<Object> regexp_err =
|
| + factory->NewSyntaxError("malformed_regexp", array);
|
| + isolate->Throw(*regexp_err);
|
| + return false;
|
| +}
|
| +
|
| +
|
| bool RegExpImpl::CompileIrregexp(Handle<JSRegExp> re, bool is_ascii) {
|
| // Compile the RegExp.
|
| Isolate* isolate = re->GetIsolate();
|
| ZoneScope zone_scope(isolate, DELETE_ON_EXIT);
|
| PostponeInterruptsScope postpone(isolate);
|
| + // If we had a compilation error the last time this is saved at the
|
| + // saved code index.
|
| Object* entry = re->DataAt(JSRegExp::code_index(is_ascii));
|
| - if (entry->IsJSObject()) {
|
| - // If it's a JSObject, a previous compilation failed and threw this object.
|
| - // Re-throw the object without trying again.
|
| - isolate->Throw(entry);
|
| + // When arriving here entry can only be a smi, either representing an
|
| + // uncompiled regexp, a previous compilation error, or code that has
|
| + // been flushed.
|
| + ASSERT(entry->IsSmi());
|
| + int entry_value = Smi::cast(entry)->value();
|
| + ASSERT(entry_value == JSRegExp::kUninitializedValue ||
|
| + entry_value == JSRegExp::kCompilationErrorValue ||
|
| + (entry_value < JSRegExp::kCodeAgeMask && entry_value >= 0));
|
| +
|
| + if (entry_value == JSRegExp::kCompilationErrorValue) {
|
| + // A previous compilation failed and threw an error which we store in
|
| + // the saved code index (we store the error message, not the actual
|
| + // error). Recreate the error object and throw it.
|
| + Object* error_string = re->DataAt(JSRegExp::saved_code_index(is_ascii));
|
| + ASSERT(error_string->IsString());
|
| + Handle<String> error_message(String::cast(error_string));
|
| + CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate);
|
| return false;
|
| }
|
| - ASSERT(entry->IsTheHole());
|
|
|
| JSRegExp::Flags flags = re->GetFlags();
|
|
|
| @@ -340,17 +379,9 @@
|
| is_ascii);
|
| if (result.error_message != NULL) {
|
| // Unable to compile regexp.
|
| - Factory* factory = isolate->factory();
|
| - Handle<FixedArray> elements = factory->NewFixedArray(2);
|
| - elements->set(0, *pattern);
|
| Handle<String> error_message =
|
| - factory->NewStringFromUtf8(CStrVector(result.error_message));
|
| - elements->set(1, *error_message);
|
| - Handle<JSArray> array = factory->NewJSArrayWithElements(elements);
|
| - Handle<Object> regexp_err =
|
| - factory->NewSyntaxError("malformed_regexp", array);
|
| - isolate->Throw(*regexp_err);
|
| - re->SetDataAt(JSRegExp::code_index(is_ascii), *regexp_err);
|
| + isolate->factory()->NewStringFromUtf8(CStrVector(result.error_message));
|
| + CreateRegExpErrorObjectAndThrow(re, is_ascii, error_message, isolate);
|
| return false;
|
| }
|
|
|
|
|