• 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/heap/heap.h"
11 #include "src/objects.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 NULL;
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_ = RegExpImpl::AtomExecRaw(regexp_,
43                                              subject_,
44                                              last_end_index,
45                                              register_array_,
46                                              register_array_size_);
47     } else {
48       int last_start_index = last_match[0];
49       if (last_start_index == last_end_index) {
50         // Zero-length match. Advance by one code point.
51         last_end_index = AdvanceZeroLength(last_end_index);
52       }
53       if (last_end_index > subject_->length()) {
54         num_matches_ = 0;  // Signal failed match.
55         return NULL;
56       }
57       num_matches_ = RegExpImpl::IrregexpExecRaw(regexp_,
58                                                  subject_,
59                                                  last_end_index,
60                                                  register_array_,
61                                                  register_array_size_);
62     }
63 
64     if (num_matches_ <= 0) return NULL;
65     current_match_index_ = 0;
66     return register_array_;
67   } else {
68     return &register_array_[current_match_index_ * registers_per_match_];
69   }
70 }
71 
72 
LastSuccessfulMatch()73 int32_t* RegExpImpl::GlobalCache::LastSuccessfulMatch() {
74   int index = current_match_index_ * registers_per_match_;
75   if (num_matches_ == 0) {
76     // After a failed match we shift back by one result.
77     index -= registers_per_match_;
78   }
79   return &register_array_[index];
80 }
81 
82 
83 }  // namespace internal
84 }  // namespace v8
85 
86 #endif  // V8_REGEXP_JSREGEXP_INL_H_
87