| Index: src/builtins/builtins-regexp.cc
|
| diff --git a/src/builtins/builtins-regexp.cc b/src/builtins/builtins-regexp.cc
|
| index fa7241941d7cc90d7a42025b405aa5f664657fd6..b8361a573a5da86d2982fa427cc0c544d74ff27c 100644
|
| --- a/src/builtins/builtins-regexp.cc
|
| +++ b/src/builtins/builtins-regexp.cc
|
| @@ -250,7 +250,7 @@ void StoreLastIndex(CodeStubAssembler* a, compiler::Node* context,
|
| compiler::Node* ConstructNewResultFromMatchInfo(Isolate* isolate,
|
| CodeStubAssembler* a,
|
| compiler::Node* context,
|
| - compiler::Node* match_elements,
|
| + compiler::Node* match_info,
|
| compiler::Node* string) {
|
| typedef CodeStubAssembler::Variable Variable;
|
| typedef CodeStubAssembler::Label Label;
|
| @@ -260,13 +260,14 @@ compiler::Node* ConstructNewResultFromMatchInfo(Isolate* isolate,
|
|
|
| CodeStubAssembler::ParameterMode mode = CodeStubAssembler::INTPTR_PARAMETERS;
|
| Node* const num_indices = a->SmiUntag(a->LoadFixedArrayElement(
|
| - match_elements, a->IntPtrConstant(RegExpImpl::kLastCaptureCount), 0,
|
| + match_info, a->IntPtrConstant(RegExpMatchInfo::kNumberOfCapturesIndex), 0,
|
| mode));
|
| Node* const num_results = a->SmiTag(a->WordShr(num_indices, 1));
|
| Node* const start = a->LoadFixedArrayElement(
|
| - match_elements, a->IntPtrConstant(RegExpImpl::kFirstCapture), 0, mode);
|
| + match_info, a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex), 0,
|
| + mode);
|
| Node* const end = a->LoadFixedArrayElement(
|
| - match_elements, a->IntPtrConstant(RegExpImpl::kFirstCapture + 1), 0,
|
| + match_info, a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 1), 0,
|
| mode);
|
|
|
| // Calculate the substring of the first match before creating the result array
|
| @@ -283,13 +284,14 @@ compiler::Node* ConstructNewResultFromMatchInfo(Isolate* isolate,
|
| a->GotoIf(a->SmiEqual(num_results, a->SmiConstant(Smi::FromInt(1))), &out);
|
|
|
| // Store all remaining captures.
|
| - Node* const limit =
|
| - a->IntPtrAdd(a->IntPtrConstant(RegExpImpl::kFirstCapture), num_indices);
|
| + Node* const limit = a->IntPtrAdd(
|
| + a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex), num_indices);
|
|
|
| Variable var_from_cursor(a, MachineType::PointerRepresentation());
|
| Variable var_to_cursor(a, MachineType::PointerRepresentation());
|
|
|
| - var_from_cursor.Bind(a->IntPtrConstant(RegExpImpl::kFirstCapture + 2));
|
| + var_from_cursor.Bind(
|
| + a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 2));
|
| var_to_cursor.Bind(a->IntPtrConstant(1));
|
|
|
| Variable* vars[] = {&var_from_cursor, &var_to_cursor};
|
| @@ -300,15 +302,14 @@ compiler::Node* ConstructNewResultFromMatchInfo(Isolate* isolate,
|
| {
|
| Node* const from_cursor = var_from_cursor.value();
|
| Node* const to_cursor = var_to_cursor.value();
|
| - Node* const start = a->LoadFixedArrayElement(match_elements, from_cursor);
|
| + Node* const start = a->LoadFixedArrayElement(match_info, from_cursor);
|
|
|
| Label next_iter(a);
|
| a->GotoIf(a->SmiEqual(start, a->SmiConstant(Smi::FromInt(-1))), &next_iter);
|
|
|
| Node* const from_cursor_plus1 =
|
| a->IntPtrAdd(from_cursor, a->IntPtrConstant(1));
|
| - Node* const end =
|
| - a->LoadFixedArrayElement(match_elements, from_cursor_plus1);
|
| + Node* const end = a->LoadFixedArrayElement(match_info, from_cursor_plus1);
|
|
|
| Node* const capture = a->SubString(context, string, start, end);
|
| a->StoreFixedArrayElement(result_elements, to_cursor, capture);
|
| @@ -419,7 +420,7 @@ void Builtins::Generate_RegExpPrototypeExec(CodeStubAssembler* a) {
|
| match_indices = a->CallStub(exec_callable, context, regexp, string,
|
| var_lastindex.value(), last_match_info);
|
|
|
| - // {match_indices} is either null or the RegExpLastMatchInfo array.
|
| + // {match_indices} is either null or the RegExpMatchInfo array.
|
| // Return early if exec failed, possibly updating last index.
|
| a->GotoUnless(a->WordEqual(match_indices, null), &successful_match);
|
|
|
| @@ -436,13 +437,12 @@ void Builtins::Generate_RegExpPrototypeExec(CodeStubAssembler* a) {
|
| Label construct_result(a);
|
| a->Bind(&successful_match);
|
| {
|
| - Node* const match_elements = a->LoadElements(match_indices);
|
| -
|
| a->GotoUnless(should_update_last_index, &construct_result);
|
|
|
| // Update the new last index from {match_indices}.
|
| Node* const new_lastindex = a->LoadFixedArrayElement(
|
| - match_elements, a->IntPtrConstant(RegExpImpl::kFirstCapture + 1));
|
| + match_indices,
|
| + a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 1));
|
|
|
| StoreLastIndex(a, context, has_initialmap, regexp, new_lastindex);
|
| a->Goto(&construct_result);
|
| @@ -450,7 +450,7 @@ void Builtins::Generate_RegExpPrototypeExec(CodeStubAssembler* a) {
|
| a->Bind(&construct_result);
|
| {
|
| Node* result = ConstructNewResultFromMatchInfo(isolate, a, context,
|
| - match_elements, string);
|
| + match_indices, string);
|
| a->Return(result);
|
| }
|
| }
|
| @@ -884,8 +884,7 @@ DEFINE_CAPTURE_GETTER(9)
|
|
|
| BUILTIN(RegExpInputGetter) {
|
| HandleScope scope(isolate);
|
| - Handle<Object> obj = RegExpUtils::GetLastMatchInput(
|
| - isolate, isolate->regexp_last_match_info());
|
| + Handle<Object> obj(isolate->regexp_last_match_info()->LastInput(), isolate);
|
| return obj->IsUndefined(isolate) ? isolate->heap()->empty_string()
|
| : String::cast(*obj);
|
| }
|
| @@ -896,8 +895,7 @@ BUILTIN(RegExpInputSetter) {
|
| Handle<String> str;
|
| ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, str,
|
| Object::ToString(isolate, value));
|
| - RegExpUtils::SetLastMatchField(isolate, isolate->regexp_last_match_info(),
|
| - RegExpImpl::kLastInput, str);
|
| + isolate->regexp_last_match_info()->SetLastInput(*str);
|
| return isolate->heap()->undefined_value();
|
| }
|
|
|
| @@ -913,9 +911,8 @@ BUILTIN(RegExpLastMatchGetter) {
|
|
|
| BUILTIN(RegExpLastParenGetter) {
|
| HandleScope scope(isolate);
|
| - Handle<JSObject> match_info = isolate->regexp_last_match_info();
|
| - const int length =
|
| - RegExpUtils::GetLastMatchNumberOfCaptures(isolate, match_info);
|
| + Handle<RegExpMatchInfo> match_info = isolate->regexp_last_match_info();
|
| + const int length = match_info->NumberOfCaptureRegisters();
|
| if (length <= 2) return isolate->heap()->empty_string(); // No captures.
|
|
|
| DCHECK_EQ(0, length % 2);
|
| @@ -929,21 +926,17 @@ BUILTIN(RegExpLastParenGetter) {
|
|
|
| BUILTIN(RegExpLeftContextGetter) {
|
| HandleScope scope(isolate);
|
| - Handle<JSObject> match_info = isolate->regexp_last_match_info();
|
| - const int start_index =
|
| - RegExpUtils::GetLastMatchCapture(isolate, match_info, 0);
|
| - Handle<String> last_subject =
|
| - RegExpUtils::GetLastMatchSubject(isolate, match_info);
|
| + Handle<RegExpMatchInfo> match_info = isolate->regexp_last_match_info();
|
| + const int start_index = match_info->Capture(0);
|
| + Handle<String> last_subject(match_info->LastSubject());
|
| return *isolate->factory()->NewSubString(last_subject, 0, start_index);
|
| }
|
|
|
| BUILTIN(RegExpRightContextGetter) {
|
| HandleScope scope(isolate);
|
| - Handle<JSObject> match_info = isolate->regexp_last_match_info();
|
| - const int start_index =
|
| - RegExpUtils::GetLastMatchCapture(isolate, match_info, 1);
|
| - Handle<String> last_subject =
|
| - RegExpUtils::GetLastMatchSubject(isolate, match_info);
|
| + Handle<RegExpMatchInfo> match_info = isolate->regexp_last_match_info();
|
| + const int start_index = match_info->Capture(1);
|
| + Handle<String> last_subject(match_info->LastSubject());
|
| const int len = last_subject->length();
|
| return *isolate->factory()->NewSubString(last_subject, start_index, len);
|
| }
|
| @@ -1138,7 +1131,7 @@ MaybeHandle<JSArray> RegExpSplit(Isolate* isolate, Handle<JSRegExp> regexp,
|
|
|
| if (limit == 0) return factory->NewJSArray(0);
|
|
|
| - Handle<JSObject> last_match_info = isolate->regexp_last_match_info();
|
| + Handle<RegExpMatchInfo> last_match_info = isolate->regexp_last_match_info();
|
|
|
| if (length == 0) {
|
| Handle<Object> match_indices;
|
| @@ -1172,7 +1165,8 @@ MaybeHandle<JSArray> RegExpSplit(Isolate* isolate, Handle<JSRegExp> regexp,
|
| Handle<Object> match_indices_obj;
|
| ASSIGN_RETURN_ON_EXCEPTION(
|
| isolate, match_indices_obj,
|
| - RegExpImpl::Exec(regexp, string, start_index, last_match_info),
|
| + RegExpImpl::Exec(regexp, string, start_index,
|
| + isolate->regexp_last_match_info()),
|
| JSArray);
|
|
|
| if (match_indices_obj->IsNull(isolate)) {
|
| @@ -1182,13 +1176,9 @@ MaybeHandle<JSArray> RegExpSplit(Isolate* isolate, Handle<JSRegExp> regexp,
|
| break;
|
| }
|
|
|
| - auto match_indices = Handle<JSReceiver>::cast(match_indices_obj);
|
| + auto match_indices = Handle<RegExpMatchInfo>::cast(match_indices_obj);
|
|
|
| - Handle<Object> start_match_obj =
|
| - JSReceiver::GetElement(isolate, match_indices,
|
| - RegExpImpl::kFirstCapture)
|
| - .ToHandleChecked();
|
| - start_match = Handle<Smi>::cast(start_match_obj)->value();
|
| + start_match = match_indices->Capture(0);
|
|
|
| if (start_match == length) {
|
| Handle<String> substr =
|
| @@ -1197,11 +1187,7 @@ MaybeHandle<JSArray> RegExpSplit(Isolate* isolate, Handle<JSRegExp> regexp,
|
| break;
|
| }
|
|
|
| - Handle<Object> end_index_obj =
|
| - JSReceiver::GetElement(isolate, match_indices,
|
| - RegExpImpl::kFirstCapture + 1)
|
| - .ToHandleChecked();
|
| - const int end_index = Handle<Smi>::cast(end_index_obj)->value();
|
| + const int end_index = match_indices->Capture(1);
|
|
|
| if (start_index == end_index && end_index == current_index) {
|
| const bool unicode = (regexp->GetFlags() & JSRegExp::kUnicode) != 0;
|
| @@ -1221,21 +1207,9 @@ MaybeHandle<JSArray> RegExpSplit(Isolate* isolate, Handle<JSRegExp> regexp,
|
|
|
| if (num_elems == limit) break;
|
|
|
| - Handle<Object> num_captures_obj =
|
| - JSReceiver::GetElement(isolate, match_indices,
|
| - RegExpImpl::kLastCaptureCount)
|
| - .ToHandleChecked();
|
| - const int match_indices_len = Handle<Smi>::cast(num_captures_obj)->value() +
|
| - RegExpImpl::kFirstCapture;
|
| -
|
| - for (int i = RegExpImpl::kFirstCapture + 2; i < match_indices_len;) {
|
| - Handle<Object> start_obj =
|
| - JSReceiver::GetElement(isolate, match_indices, i++).ToHandleChecked();
|
| - const int start = Handle<Smi>::cast(start_obj)->value();
|
| -
|
| - Handle<Object> end_obj =
|
| - JSReceiver::GetElement(isolate, match_indices, i++).ToHandleChecked();
|
| - const int end = Handle<Smi>::cast(end_obj)->value();
|
| + for (int i = 2; i < match_indices->NumberOfCaptureRegisters(); i += 2) {
|
| + const int start = match_indices->Capture(i);
|
| + const int end = match_indices->Capture(i + 1);
|
|
|
| if (end != -1) {
|
| Handle<String> substr = factory->NewSubString(string, start, end);
|
| @@ -1531,17 +1505,16 @@ compiler::Node* ReplaceFastPath(CodeStubAssembler* a, compiler::Node* context,
|
|
|
| a->Bind(&if_matched);
|
| {
|
| - Node* const match_elements = a->LoadElements(match_indices);
|
| CodeStubAssembler::ParameterMode mode =
|
| CodeStubAssembler::INTPTR_PARAMETERS;
|
|
|
| Node* const subject_start = smi_zero;
|
| Node* const match_start = a->LoadFixedArrayElement(
|
| - match_elements, a->IntPtrConstant(RegExpImpl::kFirstCapture), 0,
|
| - mode);
|
| + match_indices, a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex),
|
| + 0, mode);
|
| Node* const match_end = a->LoadFixedArrayElement(
|
| - match_elements, a->IntPtrConstant(RegExpImpl::kFirstCapture + 1), 0,
|
| - mode);
|
| + match_indices,
|
| + a->IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 1), 0, mode);
|
| Node* const subject_end = a->LoadStringLength(subject_string);
|
|
|
| Label if_replaceisempty(a), if_replaceisnotempty(a);
|
| @@ -1655,29 +1628,6 @@ void Builtins::Generate_RegExpPrototypeReplace(CodeStubAssembler* a) {
|
| }
|
| }
|
|
|
| -namespace {
|
| -
|
| -// TODO(jgruber): Replace this with a FixedArray.
|
| -compiler::Node* GetInternalMatchInfo(CodeStubAssembler* a,
|
| - compiler::Node* context) {
|
| - typedef compiler::Node Node;
|
| -
|
| - const ElementsKind elements_kind = FAST_ELEMENTS;
|
| - Node* const native_context = a->LoadNativeContext(context);
|
| - Node* const array_map =
|
| - a->LoadJSArrayElementsMap(elements_kind, native_context);
|
| - Node* const capacity = a->IntPtrConstant(RegExpImpl::kLastMatchOverhead + 2);
|
| - Node* const allocation_site = nullptr;
|
| -
|
| - Node* const smi_zero = a->SmiConstant(Smi::kZero);
|
| -
|
| - return a->AllocateJSArray(elements_kind, array_map, capacity, smi_zero,
|
| - allocation_site,
|
| - CodeStubAssembler::INTPTR_PARAMETERS);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| // Simple string matching functionality for internal use which does not modify
|
| // the last match info.
|
| void Builtins::Generate_RegExpInternalMatch(CodeStubAssembler* a) {
|
| @@ -1692,7 +1642,10 @@ void Builtins::Generate_RegExpInternalMatch(CodeStubAssembler* a) {
|
|
|
| Node* const null = a->NullConstant();
|
| Node* const smi_zero = a->SmiConstant(Smi::FromInt(0));
|
| - Node* const internal_match_info = GetInternalMatchInfo(a, context);
|
| +
|
| + Node* const native_context = a->LoadNativeContext(context);
|
| + Node* const internal_match_info = a->LoadContextElement(
|
| + native_context, Context::REGEXP_INTERNAL_MATCH_INFO_INDEX);
|
|
|
| Callable exec_callable = CodeFactory::RegExpExec(isolate);
|
| Node* const match_indices = a->CallStub(
|
| @@ -1706,9 +1659,8 @@ void Builtins::Generate_RegExpInternalMatch(CodeStubAssembler* a) {
|
|
|
| a->Bind(&if_matched);
|
| {
|
| - Node* const match_elements = a->LoadElements(match_indices);
|
| Node* result = ConstructNewResultFromMatchInfo(isolate, a, context,
|
| - match_elements, string);
|
| + match_indices, string);
|
| a->Return(result);
|
| }
|
| }
|
|
|