diff options
author | Timothy Flynn <trflynn89@pm.me> | 2021-08-14 16:28:54 -0400 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2021-08-15 11:43:45 +0100 |
commit | f1ce998d73979b80352675d6d3170399b2311913 (patch) | |
tree | ab15c8d1713571bbbf87591c7d3a8e1b0e7b5f58 /Userland/Libraries/LibJS/Runtime | |
parent | fea181bde35b115de33adb5f80c3f6abe46cec72 (diff) | |
download | serenity-f1ce998d73979b80352675d6d3170399b2311913.zip |
LibRegex+LibJS: Combine named and unnamed capture groups in MatchState
Combining these into one list helps reduce the size of MatchState, and
as a result, reduces the amount of memory consumed during execution of
very large regex matches.
Doing this also allows us to remove a few regex byte code instructions:
ClearNamedCaptureGroup, SaveLeftNamedCaptureGroup, and NamedReference.
Named groups now behave the same as unnamed groups for these operations.
Note that SaveRightNamedCaptureGroup still exists to cache the matched
group name.
This also removes the recursion level from the MatchState, as it can
exist as a local variable in Matcher::execute instead.
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp index 7a5c4fad99..ca3f4593b5 100644 --- a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp @@ -263,13 +263,16 @@ static Value regexp_builtin_exec(GlobalObject& global_object, RegExpObject& rege return {}; } - auto* array = Array::create(global_object, result.n_capture_groups + 1); + auto* array = Array::create(global_object, result.n_named_capture_groups + 1); if (vm.exception()) return {}; Vector<Optional<Match>> indices { Match::create(match) }; HashMap<String, Match> group_names; + bool has_groups = result.n_named_capture_groups != 0; + Object* groups_object = has_groups ? Object::create(global_object, nullptr) : nullptr; + for (size_t i = 0; i < result.n_capture_groups; ++i) { auto capture_value = js_undefined(); auto& capture = result.capture_group_matches[0][i + 1]; @@ -280,22 +283,15 @@ static Value regexp_builtin_exec(GlobalObject& global_object, RegExpObject& rege indices.append(Match::create(capture)); } array->create_data_property_or_throw(i + 1, capture_value); - } - - bool has_groups = result.n_named_capture_groups > 0; - Value groups = js_undefined(); - if (has_groups) { - auto groups_object = Object::create(global_object, nullptr); - - for (auto& entry : result.named_capture_group_matches[0]) { - groups_object->create_data_property_or_throw(entry.key, js_string(vm, entry.value.view.u16_view())); - group_names.set(entry.key, Match::create(entry.value)); + if (capture.capture_group_name.has_value()) { + auto group_name = capture.capture_group_name->to_string(); + groups_object->create_data_property_or_throw(group_name, js_string(vm, capture.view.u16_view())); + group_names.set(move(group_name), Match::create(capture)); } - - groups = move(groups_object); } + Value groups = has_groups ? groups_object : js_undefined(); array->create_data_property_or_throw(vm.names.groups, groups); if (has_indices) { |