| Index: src/jsregexp.cc
|
| ===================================================================
|
| --- src/jsregexp.cc (revision 1309)
|
| +++ src/jsregexp.cc (working copy)
|
| @@ -51,44 +51,10 @@
|
|
|
| #include "interpreter-irregexp.h"
|
|
|
| -// Including pcre.h undefines DEBUG to avoid getting debug output from
|
| -// the JSCRE implementation. Make sure to redefine it in debug mode
|
| -// after having included the header file.
|
| -#ifdef DEBUG
|
| -#include "third_party/jscre/pcre.h"
|
| -#define DEBUG
|
| -#else
|
| -#include "third_party/jscre/pcre.h"
|
| -#endif
|
|
|
| -
|
| namespace v8 { namespace internal {
|
|
|
|
|
| -static Failure* malloc_failure;
|
| -
|
| -static void* JSREMalloc(size_t size) {
|
| - Object* obj = Heap::AllocateByteArray(size);
|
| -
|
| - // If allocation failed, return a NULL pointer to JSRE, and jsRegExpCompile
|
| - // will return NULL to the caller, performs GC there.
|
| - // Also pass failure information to the caller.
|
| - if (obj->IsFailure()) {
|
| - malloc_failure = Failure::cast(obj);
|
| - return NULL;
|
| - }
|
| -
|
| - // Note: object is unrooted, the caller of jsRegExpCompile must
|
| - // create a handle for the return value before doing heap allocation.
|
| - return reinterpret_cast<void*>(ByteArray::cast(obj)->GetDataStartAddress());
|
| -}
|
| -
|
| -
|
| -static void JSREFree(void* p) {
|
| - USE(p); // Do nothing, memory is garbage collected.
|
| -}
|
| -
|
| -
|
| String* RegExpImpl::last_ascii_string_ = NULL;
|
| String* RegExpImpl::two_byte_cached_string_ = NULL;
|
|
|
| @@ -272,10 +238,8 @@
|
| Vector<const uc16> atom_pattern = atom->data();
|
| Handle<String> atom_string = Factory::NewStringFromTwoByte(atom_pattern);
|
| result = AtomCompile(re, pattern, flags, atom_string);
|
| - } else if (FLAG_irregexp) {
|
| - result = IrregexpPrepare(re, pattern, flags);
|
| } else {
|
| - result = JscrePrepare(re, pattern, flags);
|
| + result = IrregexpPrepare(re, pattern, flags);
|
| }
|
| Object* data = re->data();
|
| if (data->IsFixedArray()) {
|
| @@ -301,8 +265,6 @@
|
| ASSERT(!result.is_null() || Top::has_pending_exception());
|
| return result;
|
| }
|
| - case JSRegExp::JSCRE:
|
| - return JscreExec(regexp, subject, index);
|
| default:
|
| UNREACHABLE();
|
| return Handle<Object>::null();
|
| @@ -320,8 +282,6 @@
|
| ASSERT(!result.is_null() || Top::has_pending_exception());
|
| return result;
|
| }
|
| - case JSRegExp::JSCRE:
|
| - return JscreExecGlobal(regexp, subject);
|
| default:
|
| UNREACHABLE();
|
| return Handle<Object>::null();
|
| @@ -391,259 +351,6 @@
|
| }
|
|
|
|
|
| -// JSCRE implementation.
|
| -
|
| -
|
| -int RegExpImpl::JscreNumberOfCaptures(Handle<JSRegExp> re) {
|
| - FixedArray* value = FixedArray::cast(re->DataAt(JSRegExp::kJscreDataIndex));
|
| - return Smi::cast(value->get(kJscreNumberOfCapturesIndex))->value();
|
| -}
|
| -
|
| -
|
| -ByteArray* RegExpImpl::JscreInternal(Handle<JSRegExp> re) {
|
| - FixedArray* value = FixedArray::cast(re->DataAt(JSRegExp::kJscreDataIndex));
|
| - return ByteArray::cast(value->get(kJscreInternalIndex));
|
| -}
|
| -
|
| -
|
| -Handle<Object>RegExpImpl::JscrePrepare(Handle<JSRegExp> re,
|
| - Handle<String> pattern,
|
| - JSRegExp::Flags flags) {
|
| - Handle<Object> value(Heap::undefined_value());
|
| - Factory::SetRegExpData(re, JSRegExp::JSCRE, pattern, flags, value);
|
| - return re;
|
| -}
|
| -
|
| -
|
| -static inline Object* JscreDoCompile(String* pattern,
|
| - JSRegExp::Flags flags,
|
| - unsigned* number_of_captures,
|
| - const char** error_message,
|
| - v8::jscre::JscreRegExp** code) {
|
| - v8::jscre::JSRegExpIgnoreCaseOption case_option = flags.is_ignore_case()
|
| - ? v8::jscre::JSRegExpIgnoreCase
|
| - : v8::jscre::JSRegExpDoNotIgnoreCase;
|
| - v8::jscre::JSRegExpMultilineOption multiline_option = flags.is_multiline()
|
| - ? v8::jscre::JSRegExpMultiline
|
| - : v8::jscre::JSRegExpSingleLine;
|
| - *error_message = NULL;
|
| - malloc_failure = Failure::Exception();
|
| - *code = v8::jscre::jsRegExpCompile(pattern->GetTwoByteData(),
|
| - pattern->length(),
|
| - case_option,
|
| - multiline_option,
|
| - number_of_captures,
|
| - error_message,
|
| - &JSREMalloc,
|
| - &JSREFree);
|
| - if (*code == NULL && (malloc_failure->IsRetryAfterGC() ||
|
| - malloc_failure->IsOutOfMemoryFailure())) {
|
| - return malloc_failure;
|
| - } else {
|
| - // It doesn't matter which object we return here, we just need to return
|
| - // a non-failure to indicate to the GC-retry code that there was no
|
| - // allocation failure.
|
| - return pattern;
|
| - }
|
| -}
|
| -
|
| -
|
| -static void JscreCompileWithRetryAfterGC(Handle<String> pattern,
|
| - JSRegExp::Flags flags,
|
| - unsigned* number_of_captures,
|
| - const char** error_message,
|
| - v8::jscre::JscreRegExp** code) {
|
| - CALL_HEAP_FUNCTION_VOID(JscreDoCompile(*pattern,
|
| - flags,
|
| - number_of_captures,
|
| - error_message,
|
| - code));
|
| -}
|
| -
|
| -
|
| -Handle<Object> RegExpImpl::JscreCompile(Handle<JSRegExp> re) {
|
| - ASSERT_EQ(re->TypeTag(), JSRegExp::JSCRE);
|
| - ASSERT(re->DataAt(JSRegExp::kJscreDataIndex)->IsUndefined());
|
| -
|
| - Handle<String> pattern(re->Pattern());
|
| - JSRegExp::Flags flags = re->GetFlags();
|
| -
|
| - Handle<String> two_byte_pattern = StringToTwoByte(pattern);
|
| -
|
| - unsigned number_of_captures;
|
| - const char* error_message = NULL;
|
| -
|
| - v8::jscre::JscreRegExp* code = NULL;
|
| - FlattenString(pattern);
|
| -
|
| - JscreCompileWithRetryAfterGC(two_byte_pattern,
|
| - flags,
|
| - &number_of_captures,
|
| - &error_message,
|
| - &code);
|
| -
|
| - if (code == NULL) {
|
| - // Throw an exception.
|
| - Handle<JSArray> array = Factory::NewJSArray(2);
|
| - SetElement(array, 0, pattern);
|
| - const char* message =
|
| - (error_message == NULL) ? "Unknown regexp error" : error_message;
|
| - SetElement(array, 1, Factory::NewStringFromUtf8(CStrVector(message)));
|
| - Handle<Object> regexp_err =
|
| - Factory::NewSyntaxError("malformed_regexp", array);
|
| - Top::Throw(*regexp_err);
|
| - return Handle<Object>();
|
| - }
|
| -
|
| - // Convert the return address to a ByteArray pointer.
|
| - Handle<ByteArray> internal(
|
| - ByteArray::FromDataStartAddress(reinterpret_cast<Address>(code)));
|
| -
|
| - Handle<FixedArray> value = Factory::NewFixedArray(kJscreDataLength);
|
| - value->set(kJscreNumberOfCapturesIndex, Smi::FromInt(number_of_captures));
|
| - value->set(kJscreInternalIndex, *internal);
|
| - Factory::SetRegExpData(re, JSRegExp::JSCRE, pattern, flags, value);
|
| -
|
| - return re;
|
| -}
|
| -
|
| -
|
| -Handle<Object> RegExpImpl::JscreExec(Handle<JSRegExp> regexp,
|
| - Handle<String> subject,
|
| - Handle<Object> index) {
|
| - ASSERT_EQ(regexp->TypeTag(), JSRegExp::JSCRE);
|
| - if (regexp->DataAt(JSRegExp::kJscreDataIndex)->IsUndefined()) {
|
| - Handle<Object> compile_result = JscreCompile(regexp);
|
| - if (compile_result.is_null()) return compile_result;
|
| - }
|
| - ASSERT(regexp->DataAt(JSRegExp::kJscreDataIndex)->IsFixedArray());
|
| -
|
| - int num_captures = JscreNumberOfCaptures(regexp);
|
| -
|
| - OffsetsVector offsets((num_captures + 1) * 3);
|
| -
|
| - int previous_index = static_cast<int>(DoubleToInteger(index->Number()));
|
| -
|
| - Handle<String> subject16 = CachedStringToTwoByte(subject);
|
| -
|
| - return JscreExecOnce(regexp,
|
| - num_captures,
|
| - subject,
|
| - previous_index,
|
| - subject16->GetTwoByteData(),
|
| - offsets.vector(),
|
| - offsets.length());
|
| -}
|
| -
|
| -
|
| -Handle<Object> RegExpImpl::JscreExecOnce(Handle<JSRegExp> regexp,
|
| - int num_captures,
|
| - Handle<String> subject,
|
| - int previous_index,
|
| - const uc16* two_byte_subject,
|
| - int* offsets_vector,
|
| - int offsets_vector_length) {
|
| - int rc;
|
| - {
|
| - AssertNoAllocation a;
|
| - ByteArray* internal = JscreInternal(regexp);
|
| - const v8::jscre::JscreRegExp* js_regexp =
|
| - reinterpret_cast<v8::jscre::JscreRegExp*>(
|
| - internal->GetDataStartAddress());
|
| -
|
| - rc = v8::jscre::jsRegExpExecute(js_regexp,
|
| - two_byte_subject,
|
| - subject->length(),
|
| - previous_index,
|
| - offsets_vector,
|
| - offsets_vector_length);
|
| - }
|
| -
|
| - // The KJS JavaScript engine returns null (ie, a failed match) when
|
| - // JSRE's internal match limit is exceeded. We duplicate that behavior here.
|
| - if (rc == v8::jscre::JSRegExpErrorNoMatch
|
| - || rc == v8::jscre::JSRegExpErrorHitLimit) {
|
| - return Factory::null_value();
|
| - }
|
| -
|
| - // Other JSRE errors:
|
| - if (rc < 0) {
|
| - // Throw an exception.
|
| - Handle<Object> code(Smi::FromInt(rc));
|
| - Handle<Object> args[2] = { Factory::LookupAsciiSymbol("jsre_exec"), code };
|
| - Handle<Object> regexp_err(
|
| - Factory::NewTypeError("jsre_error", HandleVector(args, 2)));
|
| - return Handle<Object>(Top::Throw(*regexp_err));
|
| - }
|
| -
|
| - Handle<FixedArray> array = Factory::NewFixedArray(2 * (num_captures+1));
|
| - // The captures come in (start, end+1) pairs.
|
| - for (int i = 0; i < 2 * (num_captures+1); i += 2) {
|
| - array->set(i, Smi::FromInt(offsets_vector[i]));
|
| - array->set(i+1, Smi::FromInt(offsets_vector[i+1]));
|
| - }
|
| - return Factory::NewJSArrayWithElements(array);
|
| -}
|
| -
|
| -
|
| -Handle<Object> RegExpImpl::JscreExecGlobal(Handle<JSRegExp> regexp,
|
| - Handle<String> subject) {
|
| - ASSERT_EQ(regexp->TypeTag(), JSRegExp::JSCRE);
|
| - if (regexp->DataAt(JSRegExp::kJscreDataIndex)->IsUndefined()) {
|
| - Handle<Object> compile_result = JscreCompile(regexp);
|
| - if (compile_result.is_null()) return compile_result;
|
| - }
|
| - ASSERT(regexp->DataAt(JSRegExp::kJscreDataIndex)->IsFixedArray());
|
| -
|
| - // Prepare space for the return values.
|
| - int num_captures = JscreNumberOfCaptures(regexp);
|
| -
|
| - OffsetsVector offsets((num_captures + 1) * 3);
|
| -
|
| - int previous_index = 0;
|
| -
|
| - Handle<JSArray> result = Factory::NewJSArray(0);
|
| - int i = 0;
|
| - Handle<Object> matches;
|
| -
|
| - Handle<String> subject16 = CachedStringToTwoByte(subject);
|
| -
|
| - do {
|
| - if (previous_index > subject->length() || previous_index < 0) {
|
| - // Per ECMA-262 15.10.6.2, if the previous index is greater than the
|
| - // string length, there is no match.
|
| - matches = Factory::null_value();
|
| - } else {
|
| - matches = JscreExecOnce(regexp,
|
| - num_captures,
|
| - subject,
|
| - previous_index,
|
| - subject16->GetTwoByteData(),
|
| - offsets.vector(),
|
| - offsets.length());
|
| -
|
| - if (matches->IsJSArray()) {
|
| - SetElement(result, i, matches);
|
| - i++;
|
| - previous_index = offsets.vector()[1];
|
| - if (offsets.vector()[0] == offsets.vector()[1]) {
|
| - previous_index++;
|
| - }
|
| - }
|
| - }
|
| - } while (matches->IsJSArray());
|
| -
|
| - // If we exited the loop with an exception, throw it.
|
| - if (matches->IsNull()) {
|
| - // Exited loop normally.
|
| - return result;
|
| - } else {
|
| - // Exited loop with the exception in matches.
|
| - return matches;
|
| - }
|
| -}
|
| -
|
| -
|
| // Irregexp implementation.
|
|
|
|
|
| @@ -2070,7 +1777,7 @@
|
| // We are being asked to make a non-generic version. Keep track of how many
|
| // non-generic versions we generate so as not to overdo it.
|
| trace_count_++;
|
| - if (FLAG_irregexp_optimization &&
|
| + if (FLAG_regexp_optimization &&
|
| trace_count_ < kMaxCopiesCodeGenerated &&
|
| compiler->recursion_depth() <= RegExpCompiler::kMaxRecursion) {
|
| return CONTINUE;
|
| @@ -3237,7 +2944,7 @@
|
| if (not_at_start_) new_trace.set_at_start(Trace::FALSE);
|
| alt_gen->expects_preload = preload_is_current;
|
| bool generate_full_check_inline = false;
|
| - if (FLAG_irregexp_optimization &&
|
| + if (FLAG_regexp_optimization &&
|
| try_to_emit_quick_check_for_alternative(i) &&
|
| alternative.node()->EmitQuickCheck(compiler,
|
| &new_trace,
|
| @@ -4038,7 +3745,7 @@
|
| bool needs_capture_clearing = !capture_registers.is_empty();
|
| if (body_can_be_empty) {
|
| body_start_reg = compiler->AllocateRegister();
|
| - } else if (FLAG_irregexp_optimization && !needs_capture_clearing) {
|
| + } else if (FLAG_regexp_optimization && !needs_capture_clearing) {
|
| // Only unroll if there are no captures and the body can't be
|
| // empty.
|
| if (min > 0 && min <= kMaxUnrolledMinMatches) {
|
| @@ -4930,7 +4637,7 @@
|
|
|
| NodeInfo info = *node->info();
|
|
|
| - if (FLAG_irregexp_native) {
|
| + if (FLAG_regexp_native) {
|
| #ifdef ARM
|
| // Unimplemented, fall-through to bytecode implementation.
|
| #else // IA32
|
|
|