Commit c0766d66 authored by jgruber's avatar jgruber Committed by Commit Bot

[regexp] Typify RegExpExecInternal

Bug: v8:7754
Change-Id: Ie58571682f4dff76108180e8a707159997f7abfa
Reviewed-on: https://chromium-review.googlesource.com/1145277Reviewed-by: 's avatarPeter Marshall <petermarshall@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54606}
parent 1f82fb54
...@@ -325,11 +325,9 @@ void RegExpBuiltinsAssembler::GetStringPointers( ...@@ -325,11 +325,9 @@ void RegExpBuiltinsAssembler::GetStringPointers(
var_string_end->Bind(IntPtrAdd(string_data, to_offset)); var_string_end->Bind(IntPtrAdd(string_data, to_offset));
} }
Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, TNode<Object> RegExpBuiltinsAssembler::RegExpExecInternal(
Node* const regexp, TNode<Context> context, TNode<JSRegExp> regexp, TNode<String> string,
Node* const string, TNode<Number> last_index, TNode<FixedArray> match_info) {
Node* const last_index,
Node* const match_info) {
// Just jump directly to runtime if native RegExp is not selected at compile // Just jump directly to runtime if native RegExp is not selected at compile
// time or if regexp entry in generated code is turned off runtime switch or // time or if regexp entry in generated code is turned off runtime switch or
// at compilation. // at compilation.
...@@ -337,30 +335,20 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -337,30 +335,20 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
return CallRuntime(Runtime::kRegExpExec, context, regexp, string, last_index, return CallRuntime(Runtime::kRegExpExec, context, regexp, string, last_index,
match_info); match_info);
#else // V8_INTERPRETED_REGEXP #else // V8_INTERPRETED_REGEXP
CSA_ASSERT(this, TaggedIsNotSmi(regexp));
CSA_ASSERT(this, IsJSRegExp(regexp));
CSA_ASSERT(this, TaggedIsNotSmi(string));
CSA_ASSERT(this, IsString(string));
CSA_ASSERT(this, IsNumber(last_index));
CSA_ASSERT(this, IsFixedArrayMap(LoadReceiverMap(match_info)));
Node* const int_zero = IntPtrConstant(0);
ToDirectStringAssembler to_direct(state(), string); ToDirectStringAssembler to_direct(state(), string);
VARIABLE(var_result, MachineRepresentation::kTagged); TVARIABLE(Object, var_result);
Label out(this), atom(this), runtime(this, Label::kDeferred); Label out(this), atom(this), runtime(this, Label::kDeferred);
// External constants. // External constants.
Node* const isolate_address = TNode<ExternalReference> isolate_address =
ExternalConstant(ExternalReference::isolate_address(isolate())); ExternalConstant(ExternalReference::isolate_address(isolate()));
Node* const regexp_stack_memory_address_address = ExternalConstant( TNode<ExternalReference> regexp_stack_memory_address_address =
ExternalConstant(
ExternalReference::address_of_regexp_stack_memory_address(isolate())); ExternalReference::address_of_regexp_stack_memory_address(isolate()));
Node* const regexp_stack_memory_size_address = ExternalConstant( TNode<ExternalReference> regexp_stack_memory_size_address = ExternalConstant(
ExternalReference::address_of_regexp_stack_memory_size(isolate())); ExternalReference::address_of_regexp_stack_memory_size(isolate()));
Node* const static_offsets_vector_address = ExternalConstant( TNode<ExternalReference> static_offsets_vector_address = ExternalConstant(
ExternalReference::address_of_static_offsets_vector(isolate())); ExternalReference::address_of_static_offsets_vector(isolate()));
// At this point, last_index is definitely a canonicalized non-negative // At this point, last_index is definitely a canonicalized non-negative
...@@ -374,21 +362,18 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -374,21 +362,18 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
CSA_ASSERT(this, IsNumberPositive(last_index)); CSA_ASSERT(this, IsNumberPositive(last_index));
GotoIf(TaggedIsNotSmi(last_index), &if_failure); GotoIf(TaggedIsNotSmi(last_index), &if_failure);
Node* const int_string_length = LoadStringLengthAsWord(string); TNode<IntPtrT> int_string_length = LoadStringLengthAsWord(string);
Node* const int_last_index = SmiUntag(last_index); TNode<IntPtrT> int_last_index = SmiUntag(CAST(last_index));
GotoIf(UintPtrGreaterThan(int_last_index, int_string_length), &if_failure); GotoIf(UintPtrGreaterThan(int_last_index, int_string_length), &if_failure);
Node* const data = LoadObjectField(regexp, JSRegExp::kDataOffset); // Since the RegExp has been compiled, data contains a fixed array.
TNode<FixedArray> data = CAST(LoadObjectField(regexp, JSRegExp::kDataOffset));
{ {
// Check that the RegExp has been compiled (data contains a fixed array).
CSA_ASSERT(this, TaggedIsNotSmi(data));
CSA_ASSERT(this, HasInstanceType(data, FIXED_ARRAY_TYPE));
// Dispatch on the type of the RegExp. // Dispatch on the type of the RegExp.
{ {
Label next(this), unreachable(this, Label::kDeferred); Label next(this), unreachable(this, Label::kDeferred);
Node* const tag = LoadAndUntagToWord32FixedArrayElement( TNode<Int32T> tag = LoadAndUntagToWord32FixedArrayElement(
data, IntPtrConstant(JSRegExp::kTagIndex)); data, IntPtrConstant(JSRegExp::kTagIndex));
int32_t values[] = { int32_t values[] = {
...@@ -407,22 +392,21 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -407,22 +392,21 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
// Check (number_of_captures + 1) * 2 <= offsets vector size // Check (number_of_captures + 1) * 2 <= offsets vector size
// Or number_of_captures <= offsets vector size / 2 - 1 // Or number_of_captures <= offsets vector size / 2 - 1
TNode<Smi> const capture_count = TNode<Smi> capture_count =
CAST(LoadFixedArrayElement(data, JSRegExp::kIrregexpCaptureCountIndex)); CAST(LoadFixedArrayElement(data, JSRegExp::kIrregexpCaptureCountIndex));
STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2); const int kOffsetsSize = Isolate::kJSRegexpStaticOffsetsVectorSize;
GotoIf(SmiAbove( STATIC_ASSERT(kOffsetsSize >= 2);
capture_count, GotoIf(SmiAbove(capture_count, SmiConstant(kOffsetsSize / 2 - 1)),
SmiConstant(Isolate::kJSRegexpStaticOffsetsVectorSize / 2 - 1)),
&runtime); &runtime);
} }
// Ensure that a RegExp stack is allocated. This check is after branching off // Ensure that a RegExp stack is allocated. This check is after branching off
// for ATOM regexps to avoid unnecessary trips to runtime. // for ATOM regexps to avoid unnecessary trips to runtime.
{ {
Node* const stack_size = TNode<IntPtrT> stack_size = UncheckedCast<IntPtrT>(
Load(MachineType::IntPtr(), regexp_stack_memory_size_address); Load(MachineType::IntPtr(), regexp_stack_memory_size_address));
GotoIf(IntPtrEqual(stack_size, int_zero), &runtime); GotoIf(IntPtrEqual(stack_size, IntPtrConstant(0)), &runtime);
} }
// Unpack the string if possible. // Unpack the string if possible.
...@@ -432,12 +416,12 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -432,12 +416,12 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
// Load the irregexp code object and offsets into the subject string. Both // Load the irregexp code object and offsets into the subject string. Both
// depend on whether the string is one- or two-byte. // depend on whether the string is one- or two-byte.
VARIABLE(var_string_start, MachineType::PointerRepresentation()); TVARIABLE(RawPtrT, var_string_start);
VARIABLE(var_string_end, MachineType::PointerRepresentation()); TVARIABLE(RawPtrT, var_string_end);
VARIABLE(var_code, MachineRepresentation::kTagged); TVARIABLE(Object, var_code);
{ {
Node* const direct_string_data = to_direct.PointerToData(&runtime); TNode<RawPtrT> direct_string_data = to_direct.PointerToData(&runtime);
Label next(this), if_isonebyte(this), if_istwobyte(this, Label::kDeferred); Label next(this), if_isonebyte(this), if_istwobyte(this, Label::kDeferred);
Branch(IsOneByteStringInstanceType(to_direct.instance_type()), Branch(IsOneByteStringInstanceType(to_direct.instance_type()),
...@@ -448,8 +432,8 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -448,8 +432,8 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
GetStringPointers(direct_string_data, to_direct.offset(), int_last_index, GetStringPointers(direct_string_data, to_direct.offset(), int_last_index,
int_string_length, String::ONE_BYTE_ENCODING, int_string_length, String::ONE_BYTE_ENCODING,
&var_string_start, &var_string_end); &var_string_start, &var_string_end);
var_code.Bind( var_code =
LoadFixedArrayElement(data, JSRegExp::kIrregexpLatin1CodeIndex)); LoadFixedArrayElement(data, JSRegExp::kIrregexpLatin1CodeIndex);
Goto(&next); Goto(&next);
} }
...@@ -458,8 +442,7 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -458,8 +442,7 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
GetStringPointers(direct_string_data, to_direct.offset(), int_last_index, GetStringPointers(direct_string_data, to_direct.offset(), int_last_index,
int_string_length, String::TWO_BYTE_ENCODING, int_string_length, String::TWO_BYTE_ENCODING,
&var_string_start, &var_string_end); &var_string_start, &var_string_end);
var_code.Bind( var_code = LoadFixedArrayElement(data, JSRegExp::kIrregexpUC16CodeIndex);
LoadFixedArrayElement(data, JSRegExp::kIrregexpUC16CodeIndex));
Goto(&next); Goto(&next);
} }
...@@ -469,15 +452,19 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -469,15 +452,19 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
// Check that the irregexp code has been generated for the actual string // Check that the irregexp code has been generated for the actual string
// encoding. If it has, the field contains a code object; and otherwise it // encoding. If it has, the field contains a code object; and otherwise it
// contains the uninitialized sentinel as a smi. // contains the uninitialized sentinel as a smi.
#ifdef DEBUG
{
Label next(this);
GotoIfNot(TaggedIsSmi(var_code.value()), &next);
CSA_ASSERT(this, SmiEqual(CAST(var_code.value()),
SmiConstant(JSRegExp::kUninitializedValue)));
Goto(&next);
BIND(&next);
}
#endif
Node* const code = var_code.value(); GotoIf(TaggedIsSmi(var_code.value()), &runtime);
CSA_ASSERT_BRANCH(this, [=](Label* ok, Label* not_ok) { TNode<Code> code = CAST(var_code.value());
GotoIfNot(TaggedIsSmi(code), ok);
Branch(SmiEqual(CAST(code), SmiConstant(JSRegExp::kUninitializedValue)), ok,
not_ok);
});
GotoIf(TaggedIsSmi(code), &runtime);
CSA_ASSERT(this, HasInstanceType(code, CODE_TYPE));
Label if_success(this), if_exception(this, Label::kDeferred); Label if_success(this), if_exception(this, Label::kDeferred);
{ {
...@@ -494,61 +481,62 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -494,61 +481,62 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
// Argument 0: Original subject string. // Argument 0: Original subject string.
MachineType arg0_type = type_tagged; MachineType arg0_type = type_tagged;
Node* const arg0 = string; TNode<String> arg0 = string;
// Argument 1: Previous index. // Argument 1: Previous index.
MachineType arg1_type = type_int32; MachineType arg1_type = type_int32;
Node* const arg1 = TruncateIntPtrToInt32(int_last_index); TNode<Int32T> arg1 = TruncateIntPtrToInt32(int_last_index);
// Argument 2: Start of string data. // Argument 2: Start of string data.
MachineType arg2_type = type_ptr; MachineType arg2_type = type_ptr;
Node* const arg2 = var_string_start.value(); TNode<RawPtrT> arg2 = var_string_start.value();
// Argument 3: End of string data. // Argument 3: End of string data.
MachineType arg3_type = type_ptr; MachineType arg3_type = type_ptr;
Node* const arg3 = var_string_end.value(); TNode<RawPtrT> arg3 = var_string_end.value();
// Argument 4: static offsets vector buffer. // Argument 4: static offsets vector buffer.
MachineType arg4_type = type_ptr; MachineType arg4_type = type_ptr;
Node* const arg4 = static_offsets_vector_address; TNode<ExternalReference> arg4 = static_offsets_vector_address;
// Argument 5: Set the number of capture registers to zero to force global // Argument 5: Set the number of capture registers to zero to force global
// regexps to behave as non-global. This does not affect non-global // regexps to behave as non-global. This does not affect non-global
// regexps. // regexps.
MachineType arg5_type = type_int32; MachineType arg5_type = type_int32;
Node* const arg5 = Int32Constant(0); TNode<Int32T> arg5 = Int32Constant(0);
// Argument 6: Start (high end) of backtracking stack memory area. // Argument 6: Start (high end) of backtracking stack memory area.
Node* const stack_start = TNode<RawPtrT> stack_start = UncheckedCast<RawPtrT>(
Load(MachineType::Pointer(), regexp_stack_memory_address_address); Load(MachineType::Pointer(), regexp_stack_memory_address_address));
Node* const stack_size = TNode<IntPtrT> stack_size = UncheckedCast<IntPtrT>(
Load(MachineType::IntPtr(), regexp_stack_memory_size_address); Load(MachineType::IntPtr(), regexp_stack_memory_size_address));
Node* const stack_end = IntPtrAdd(stack_start, stack_size); TNode<RawPtrT> stack_end =
ReinterpretCast<RawPtrT>(IntPtrAdd(stack_start, stack_size));
MachineType arg6_type = type_ptr; MachineType arg6_type = type_ptr;
Node* const arg6 = stack_end; TNode<RawPtrT> arg6 = stack_end;
// Argument 7: Indicate that this is a direct call from JavaScript. // Argument 7: Indicate that this is a direct call from JavaScript.
MachineType arg7_type = type_int32; MachineType arg7_type = type_int32;
Node* const arg7 = Int32Constant(1); TNode<Int32T> arg7 = Int32Constant(1);
// Argument 8: Pass current isolate address. // Argument 8: Pass current isolate address.
MachineType arg8_type = type_ptr; MachineType arg8_type = type_ptr;
Node* const arg8 = isolate_address; TNode<ExternalReference> arg8 = isolate_address;
Node* const code_entry = TNode<RawPtrT> code_entry = ReinterpretCast<RawPtrT>(
IntPtrAdd(BitcastTaggedToWord(code), IntPtrAdd(BitcastTaggedToWord(code),
IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)); IntPtrConstant(Code::kHeaderSize - kHeapObjectTag)));
Node* const result = CallCFunction9( TNode<Int32T> result = UncheckedCast<Int32T>(CallCFunction9(
retval_type, arg0_type, arg1_type, arg2_type, arg3_type, arg4_type, retval_type, arg0_type, arg1_type, arg2_type, arg3_type, arg4_type,
arg5_type, arg6_type, arg7_type, arg8_type, code_entry, arg0, arg1, arg5_type, arg6_type, arg7_type, arg8_type, code_entry, arg0, arg1,
arg2, arg3, arg4, arg5, arg6, arg7, arg8); arg2, arg3, arg4, arg5, arg6, arg7, arg8));
// Check the result. // Check the result.
// We expect exactly one result since we force the called regexp to behave // We expect exactly one result since we force the called regexp to behave
// as non-global. // as non-global.
Node* const int_result = ChangeInt32ToIntPtr(result); TNode<IntPtrT> int_result = ChangeInt32ToIntPtr(result);
GotoIf(IntPtrEqual(int_result, GotoIf(IntPtrEqual(int_result,
IntPtrConstant(NativeRegExpMacroAssembler::SUCCESS)), IntPtrConstant(NativeRegExpMacroAssembler::SUCCESS)),
&if_success); &if_success);
...@@ -570,13 +558,13 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -570,13 +558,13 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
// Check that the last match info has space for the capture registers and // Check that the last match info has space for the capture registers and
// the additional information. Ensure no overflow in add. // the additional information. Ensure no overflow in add.
STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset); STATIC_ASSERT(FixedArray::kMaxLength < kMaxInt - FixedArray::kLengthOffset);
TNode<Smi> const available_slots = TNode<Smi> available_slots =
SmiSub(LoadFixedArrayBaseLength(match_info), SmiSub(LoadFixedArrayBaseLength(match_info),
SmiConstant(RegExpMatchInfo::kLastMatchOverhead)); SmiConstant(RegExpMatchInfo::kLastMatchOverhead));
TNode<Smi> const capture_count = TNode<Smi> capture_count =
CAST(LoadFixedArrayElement(data, JSRegExp::kIrregexpCaptureCountIndex)); CAST(LoadFixedArrayElement(data, JSRegExp::kIrregexpCaptureCountIndex));
// Calculate number of register_count = (capture_count + 1) * 2. // Calculate number of register_count = (capture_count + 1) * 2.
TNode<Smi> const register_count = TNode<Smi> register_count =
SmiShl(SmiAdd(capture_count, SmiConstant(1)), 1); SmiShl(SmiAdd(capture_count, SmiConstant(1)), 1);
GotoIf(SmiGreaterThan(register_count, available_slots), &runtime); GotoIf(SmiGreaterThan(register_count, available_slots), &runtime);
...@@ -591,21 +579,21 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -591,21 +579,21 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
// Fill match and capture offsets in match_info. // Fill match and capture offsets in match_info.
{ {
Node* const limit_offset = ElementOffsetFromIndex( TNode<IntPtrT> limit_offset = ElementOffsetFromIndex(
register_count, INT32_ELEMENTS, SMI_PARAMETERS, 0); register_count, INT32_ELEMENTS, SMI_PARAMETERS, 0);
Node* const to_offset = ElementOffsetFromIndex( TNode<IntPtrT> to_offset = ElementOffsetFromIndex(
IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex), PACKED_ELEMENTS, IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex), PACKED_ELEMENTS,
INTPTR_PARAMETERS, RegExpMatchInfo::kHeaderSize - kHeapObjectTag); INTPTR_PARAMETERS, RegExpMatchInfo::kHeaderSize - kHeapObjectTag);
VARIABLE(var_to_offset, MachineType::PointerRepresentation(), to_offset); TVARIABLE(IntPtrT, var_to_offset, to_offset);
VariableList vars({&var_to_offset}, zone()); VariableList vars({&var_to_offset}, zone());
BuildFastLoop( BuildFastLoop(
vars, int_zero, limit_offset, vars, IntPtrConstant(0), limit_offset,
[=, &var_to_offset](Node* offset) { [=, &var_to_offset](Node* offset) {
Node* const value = Load(MachineType::Int32(), TNode<Int32T> value = UncheckedCast<Int32T>(Load(
static_offsets_vector_address, offset); MachineType::Int32(), static_offsets_vector_address, offset));
Node* const smi_value = SmiFromInt32(value); TNode<Smi> smi_value = SmiFromInt32(value);
StoreNoWriteBarrier(MachineRepresentation::kTagged, match_info, StoreNoWriteBarrier(MachineRepresentation::kTagged, match_info,
var_to_offset.value(), smi_value); var_to_offset.value(), smi_value);
Increment(&var_to_offset, kPointerSize); Increment(&var_to_offset, kPointerSize);
...@@ -613,13 +601,13 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -613,13 +601,13 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
kInt32Size, INTPTR_PARAMETERS, IndexAdvanceMode::kPost); kInt32Size, INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
} }
var_result.Bind(match_info); var_result = match_info;
Goto(&out); Goto(&out);
} }
BIND(&if_failure); BIND(&if_failure);
{ {
var_result.Bind(NullConstant()); var_result = NullConstant();
Goto(&out); Goto(&out);
} }
...@@ -627,7 +615,7 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -627,7 +615,7 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
{ {
// A stack overflow was detected in RegExp code. // A stack overflow was detected in RegExp code.
#ifdef DEBUG #ifdef DEBUG
Node* const pending_exception_address = TNode<ExternalReference> pending_exception_address =
ExternalConstant(ExternalReference::Create( ExternalConstant(ExternalReference::Create(
IsolateAddressId::kPendingExceptionAddress, isolate())); IsolateAddressId::kPendingExceptionAddress, isolate()));
CSA_ASSERT(this, IsTheHole(Load(MachineType::AnyTagged(), CSA_ASSERT(this, IsTheHole(Load(MachineType::AnyTagged(),
...@@ -639,9 +627,8 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -639,9 +627,8 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
BIND(&runtime); BIND(&runtime);
{ {
Node* const result = CallRuntime(Runtime::kRegExpExec, context, regexp, var_result = CallRuntime(Runtime::kRegExpExec, context, regexp, string,
string, last_index, match_info); last_index, match_info);
var_result.Bind(result);
Goto(&out); Goto(&out);
} }
...@@ -649,9 +636,8 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context, ...@@ -649,9 +636,8 @@ Node* RegExpBuiltinsAssembler::RegExpExecInternal(Node* const context,
{ {
// TODO(jgruber): A call with 4 args stresses register allocation, this // TODO(jgruber): A call with 4 args stresses register allocation, this
// should probably just be inlined. // should probably just be inlined.
Node* const result = CallBuiltin(Builtins::kRegExpExecAtom, context, regexp, var_result = CallBuiltin(Builtins::kRegExpExecAtom, context, regexp, string,
string, last_index, match_info); last_index, match_info);
var_result.Bind(result);
Goto(&out); Goto(&out);
} }
...@@ -758,8 +744,9 @@ Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult( ...@@ -758,8 +744,9 @@ Node* RegExpBuiltinsAssembler::RegExpPrototypeExecBodyWithoutResult(
native_context, Context::REGEXP_LAST_MATCH_INFO_INDEX); native_context, Context::REGEXP_LAST_MATCH_INFO_INDEX);
// Call the exec stub. // Call the exec stub.
match_indices = RegExpExecInternal(context, regexp, string, match_indices =
var_lastindex.value(), last_match_info); RegExpExecInternal(CAST(context), CAST(regexp), CAST(string),
CAST(var_lastindex.value()), CAST(last_match_info));
var_result.Bind(match_indices); var_result.Bind(match_indices);
// {match_indices} is either null or the RegExpMatchInfo array. // {match_indices} is either null or the RegExpMatchInfo array.
......
...@@ -58,9 +58,10 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler { ...@@ -58,9 +58,10 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
Variable* var_string_end); Variable* var_string_end);
// Low level logic around the actual call into pattern matching code. // Low level logic around the actual call into pattern matching code.
Node* RegExpExecInternal(Node* const context, Node* const regexp, TNode<Object> RegExpExecInternal(TNode<Context> context,
Node* const string, Node* const last_index, TNode<JSRegExp> regexp, TNode<String> string,
Node* const match_info); TNode<Number> last_index,
TNode<FixedArray> match_info);
Node* ConstructNewResultFromMatchInfo(Node* const context, Node* const regexp, Node* ConstructNewResultFromMatchInfo(Node* const context, Node* const regexp,
Node* const match_info, Node* const match_info,
......
...@@ -6088,11 +6088,11 @@ TNode<String> ToDirectStringAssembler::TryToDirect(Label* if_bailout) { ...@@ -6088,11 +6088,11 @@ TNode<String> ToDirectStringAssembler::TryToDirect(Label* if_bailout) {
return CAST(var_string_.value()); return CAST(var_string_.value());
} }
Node* ToDirectStringAssembler::TryToSequential(StringPointerKind ptr_kind, TNode<RawPtrT> ToDirectStringAssembler::TryToSequential(
Label* if_bailout) { StringPointerKind ptr_kind, Label* if_bailout) {
CHECK(ptr_kind == PTR_TO_DATA || ptr_kind == PTR_TO_STRING); CHECK(ptr_kind == PTR_TO_DATA || ptr_kind == PTR_TO_STRING);
VARIABLE(var_result, MachineType::PointerRepresentation()); TVARIABLE(RawPtrT, var_result);
Label out(this), if_issequential(this), if_isexternal(this, Label::kDeferred); Label out(this), if_issequential(this), if_isexternal(this, Label::kDeferred);
Branch(is_external(), &if_isexternal, &if_issequential); Branch(is_external(), &if_isexternal, &if_issequential);
...@@ -6100,12 +6100,12 @@ Node* ToDirectStringAssembler::TryToSequential(StringPointerKind ptr_kind, ...@@ -6100,12 +6100,12 @@ Node* ToDirectStringAssembler::TryToSequential(StringPointerKind ptr_kind,
{ {
STATIC_ASSERT(SeqOneByteString::kHeaderSize == STATIC_ASSERT(SeqOneByteString::kHeaderSize ==
SeqTwoByteString::kHeaderSize); SeqTwoByteString::kHeaderSize);
Node* result = BitcastTaggedToWord(var_string_.value()); TNode<IntPtrT> result = BitcastTaggedToWord(var_string_.value());
if (ptr_kind == PTR_TO_DATA) { if (ptr_kind == PTR_TO_DATA) {
result = IntPtrAdd(result, IntPtrConstant(SeqOneByteString::kHeaderSize - result = IntPtrAdd(result, IntPtrConstant(SeqOneByteString::kHeaderSize -
kHeapObjectTag)); kHeapObjectTag));
} }
var_result.Bind(result); var_result = ReinterpretCast<RawPtrT>(result);
Goto(&out); Goto(&out);
} }
...@@ -6114,14 +6114,14 @@ Node* ToDirectStringAssembler::TryToSequential(StringPointerKind ptr_kind, ...@@ -6114,14 +6114,14 @@ Node* ToDirectStringAssembler::TryToSequential(StringPointerKind ptr_kind,
GotoIf(IsShortExternalStringInstanceType(var_instance_type_.value()), GotoIf(IsShortExternalStringInstanceType(var_instance_type_.value()),
if_bailout); if_bailout);
Node* const string = var_string_.value(); TNode<String> string = CAST(var_string_.value());
Node* result = LoadObjectField(string, ExternalString::kResourceDataOffset, TNode<IntPtrT> result =
MachineType::Pointer()); LoadObjectField<IntPtrT>(string, ExternalString::kResourceDataOffset);
if (ptr_kind == PTR_TO_STRING) { if (ptr_kind == PTR_TO_STRING) {
result = IntPtrSub(result, IntPtrConstant(SeqOneByteString::kHeaderSize - result = IntPtrSub(result, IntPtrConstant(SeqOneByteString::kHeaderSize -
kHeapObjectTag)); kHeapObjectTag));
} }
var_result.Bind(result); var_result = ReinterpretCast<RawPtrT>(result);
Goto(&out); Goto(&out);
} }
......
...@@ -2946,13 +2946,13 @@ class ToDirectStringAssembler : public CodeStubAssembler { ...@@ -2946,13 +2946,13 @@ class ToDirectStringAssembler : public CodeStubAssembler {
// Returns a pointer to the beginning of the string data. // Returns a pointer to the beginning of the string data.
// Jumps to if_bailout if the external string cannot be unpacked. // Jumps to if_bailout if the external string cannot be unpacked.
Node* PointerToData(Label* if_bailout) { TNode<RawPtrT> PointerToData(Label* if_bailout) {
return TryToSequential(PTR_TO_DATA, if_bailout); return TryToSequential(PTR_TO_DATA, if_bailout);
} }
// Returns a pointer that, offset-wise, looks like a String. // Returns a pointer that, offset-wise, looks like a String.
// Jumps to if_bailout if the external string cannot be unpacked. // Jumps to if_bailout if the external string cannot be unpacked.
Node* PointerToString(Label* if_bailout) { TNode<RawPtrT> PointerToString(Label* if_bailout) {
return TryToSequential(PTR_TO_STRING, if_bailout); return TryToSequential(PTR_TO_STRING, if_bailout);
} }
...@@ -2964,7 +2964,7 @@ class ToDirectStringAssembler : public CodeStubAssembler { ...@@ -2964,7 +2964,7 @@ class ToDirectStringAssembler : public CodeStubAssembler {
Node* is_external() { return var_is_external_.value(); } Node* is_external() { return var_is_external_.value(); }
private: private:
Node* TryToSequential(StringPointerKind ptr_kind, Label* if_bailout); TNode<RawPtrT> TryToSequential(StringPointerKind ptr_kind, Label* if_bailout);
Variable var_string_; Variable var_string_;
Variable var_instance_type_; Variable var_instance_type_;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment