• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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         &register_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 &register_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 &register_array_[index];
76 }
77 
78 
79 }  // namespace internal
80 }  // namespace v8
81 
82 #endif  // V8_REGEXP_JSREGEXP_INL_H_
83