| Index: src/regexp-macro-assembler.cc
|
| diff --git a/src/regexp-macro-assembler.cc b/src/regexp-macro-assembler.cc
|
| index 90ac1b9fa34f61e1b0a3210e043fc7e838d851d5..6228ce4b5337edb4071553dfb153093a095f7365 100644
|
| --- a/src/regexp-macro-assembler.cc
|
| +++ b/src/regexp-macro-assembler.cc
|
| @@ -42,30 +42,82 @@ bool NativeRegExpMacroAssembler::CanReadUnaligned() {
|
| const byte* NativeRegExpMacroAssembler::StringCharacterPosition(
|
| String* subject,
|
| int start_index) {
|
| - // Not just flat, but ultra flat.
|
| - DCHECK(subject->IsExternalString() || subject->IsSeqString());
|
| + if (subject->IsConsString()) {
|
| + subject = ConsString::cast(subject)->first();
|
| + } else if (subject->IsSlicedString()) {
|
| + start_index += SlicedString::cast(subject)->offset();
|
| + subject = SlicedString::cast(subject)->parent();
|
| + }
|
| DCHECK(start_index >= 0);
|
| DCHECK(start_index <= subject->length());
|
| - if (subject->IsOneByteRepresentation()) {
|
| - const byte* address;
|
| - if (StringShape(subject).IsExternal()) {
|
| - const uint8_t* data = ExternalOneByteString::cast(subject)->GetChars();
|
| - address = reinterpret_cast<const byte*>(data);
|
| - } else {
|
| - DCHECK(subject->IsSeqOneByteString());
|
| - const uint8_t* data = SeqOneByteString::cast(subject)->GetChars();
|
| - address = reinterpret_cast<const byte*>(data);
|
| - }
|
| - return address + start_index;
|
| + if (subject->IsSeqOneByteString()) {
|
| + return reinterpret_cast<const byte*>(
|
| + SeqOneByteString::cast(subject)->GetChars() + start_index);
|
| + } else if (subject->IsSeqTwoByteString()) {
|
| + return reinterpret_cast<const byte*>(
|
| + SeqTwoByteString::cast(subject)->GetChars() + start_index);
|
| + } else if (subject->IsExternalOneByteString()) {
|
| + return reinterpret_cast<const byte*>(
|
| + ExternalOneByteString::cast(subject)->GetChars() + start_index);
|
| + } else {
|
| + return reinterpret_cast<const byte*>(
|
| + ExternalTwoByteString::cast(subject)->GetChars() + start_index);
|
| }
|
| - const uc16* data;
|
| - if (StringShape(subject).IsExternal()) {
|
| - data = ExternalTwoByteString::cast(subject)->GetChars();
|
| +}
|
| +
|
| +
|
| +int NativeRegExpMacroAssembler::CheckStackGuardState(
|
| + Isolate* isolate, int start_index, bool is_direct_call,
|
| + Address* return_address, Code* re_code, String** subject,
|
| + const byte** input_start, const byte** input_end) {
|
| + DCHECK(re_code->instruction_start() <= *return_address);
|
| + DCHECK(*return_address <= re_code->instruction_end());
|
| + int return_value = 0;
|
| + // Prepare for possible GC.
|
| + HandleScope handles(isolate);
|
| + Handle<Code> code_handle(re_code);
|
| + Handle<String> subject_handle(*subject);
|
| + bool is_one_byte = subject_handle->IsOneByteRepresentationUnderneath();
|
| +
|
| + StackLimitCheck check(isolate);
|
| + if (check.JsHasOverflowed()) {
|
| + isolate->StackOverflow();
|
| + return_value = EXCEPTION;
|
| + } else if (is_direct_call) {
|
| + // If not real stack overflow the stack guard was used to interrupt
|
| + // execution for another purpose. If this is a direct call from JavaScript
|
| + // retry the RegExp forcing the call through the runtime system.
|
| + // Currently the direct call cannot handle a GC.
|
| + return_value = RETRY;
|
| } else {
|
| - DCHECK(subject->IsSeqTwoByteString());
|
| - data = SeqTwoByteString::cast(subject)->GetChars();
|
| + Object* result = isolate->stack_guard()->HandleInterrupts();
|
| + if (result->IsException()) return_value = EXCEPTION;
|
| + }
|
| +
|
| + DisallowHeapAllocation no_gc;
|
| +
|
| + if (*code_handle != re_code) { // Return address no longer valid
|
| + intptr_t delta = code_handle->address() - re_code->address();
|
| + // Overwrite the return address on the stack.
|
| + *return_address += delta;
|
| + }
|
| +
|
| + // If we continue, we need to update the subject string addresses.
|
| + if (return_value == 0) {
|
| + // String encoding might have changed.
|
| + if (subject_handle->IsOneByteRepresentationUnderneath() != is_one_byte) {
|
| + // If we changed between an LATIN1 and an UC16 string, the specialized
|
| + // code cannot be used, and we need to restart regexp matching from
|
| + // scratch (including, potentially, compiling a new version of the code).
|
| + return_value = RETRY;
|
| + } else {
|
| + *subject = *subject_handle;
|
| + intptr_t byte_length = *input_end - *input_start;
|
| + *input_start = StringCharacterPosition(*subject, start_index);
|
| + *input_end = *input_start + byte_length;
|
| + }
|
| }
|
| - return reinterpret_cast<const byte*>(data + start_index);
|
| + return return_value;
|
| }
|
|
|
|
|
|
|