1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5
6 #ifndef V8_REGEXP_JSREGEXP_INL_H_
7 #define V8_REGEXP_JSREGEXP_INL_H_
8
9 #include "src/allocation.h"
10 #include "src/objects.h"
11 #include "src/objects/js-regexp-inl.h"
12 #include "src/regexp/jsregexp.h"
13
14 namespace v8 {
15 namespace internal {
16
17
~GlobalCache()18 RegExpImpl::GlobalCache::~GlobalCache() {
19 // Deallocate the register array if we allocated it in the constructor
20 // (as opposed to using the existing jsregexp_static_offsets_vector).
21 if (register_array_size_ > Isolate::kJSRegexpStaticOffsetsVectorSize) {
22 DeleteArray(register_array_);
23 }
24 }
25
26
FetchNext()27 int32_t* RegExpImpl::GlobalCache::FetchNext() {
28 current_match_index_++;
29 if (current_match_index_ >= num_matches_) {
30 // Current batch of results exhausted.
31 // Fail if last batch was not even fully filled.
32 if (num_matches_ < max_matches_) {
33 num_matches_ = 0; // Signal failed match.
34 return nullptr;
35 }
36
37 int32_t* last_match =
38 ®ister_array_[(current_match_index_ - 1) * registers_per_match_];
39 int last_end_index = last_match[1];
40
41 if (regexp_->TypeTag() == JSRegExp::ATOM) {
42 num_matches_ =
43 RegExpImpl::AtomExecRaw(isolate_, regexp_, subject_, last_end_index,
44 register_array_, register_array_size_);
45 } else {
46 int last_start_index = last_match[0];
47 if (last_start_index == last_end_index) {
48 // Zero-length match. Advance by one code point.
49 last_end_index = AdvanceZeroLength(last_end_index);
50 }
51 if (last_end_index > subject_->length()) {
52 num_matches_ = 0; // Signal failed match.
53 return nullptr;
54 }
55 num_matches_ = RegExpImpl::IrregexpExecRaw(
56 isolate_, regexp_, subject_, last_end_index, register_array_,
57 register_array_size_);
58 }
59
60 if (num_matches_ <= 0) return nullptr;
61 current_match_index_ = 0;
62 return register_array_;
63 } else {
64 return ®ister_array_[current_match_index_ * registers_per_match_];
65 }
66 }
67
68
LastSuccessfulMatch()69 int32_t* RegExpImpl::GlobalCache::LastSuccessfulMatch() {
70 int index = current_match_index_ * registers_per_match_;
71 if (num_matches_ == 0) {
72 // After a failed match we shift back by one result.
73 index -= registers_per_match_;
74 }
75 return ®ister_array_[index];
76 }
77
78
79 } // namespace internal
80 } // namespace v8
81
82 #endif // V8_REGEXP_JSREGEXP_INL_H_
83