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_JSREGEXP_INL_H_
7 #define V8_JSREGEXP_INL_H_
8 
9 #include "src/allocation.h"
10 #include "src/handles.h"
11 #include "src/heap/heap.h"
12 #include "src/jsregexp.h"
13 #include "src/objects.h"
14 
15 namespace v8 {
16 namespace internal {
17 
18 
~GlobalCache()19 RegExpImpl::GlobalCache::~GlobalCache() {
20   // Deallocate the register array if we allocated it in the constructor
21   // (as opposed to using the existing jsregexp_static_offsets_vector).
22   if (register_array_size_ > Isolate::kJSRegexpStaticOffsetsVectorSize) {
23     DeleteArray(register_array_);
24   }
25 }
26 
27 
FetchNext()28 int32_t* RegExpImpl::GlobalCache::FetchNext() {
29   current_match_index_++;
30   if (current_match_index_ >= num_matches_) {
31     // Current batch of results exhausted.
32     // Fail if last batch was not even fully filled.
33     if (num_matches_ < max_matches_) {
34       num_matches_ = 0;  // Signal failed match.
35       return NULL;
36     }
37 
38     int32_t* last_match =
39         &register_array_[(current_match_index_ - 1) * registers_per_match_];
40     int last_end_index = last_match[1];
41 
42     if (regexp_->TypeTag() == JSRegExp::ATOM) {
43       num_matches_ = RegExpImpl::AtomExecRaw(regexp_,
44                                              subject_,
45                                              last_end_index,
46                                              register_array_,
47                                              register_array_size_);
48     } else {
49       int last_start_index = last_match[0];
50       if (last_start_index == last_end_index) last_end_index++;
51       if (last_end_index > subject_->length()) {
52         num_matches_ = 0;  // Signal failed match.
53         return NULL;
54       }
55       num_matches_ = RegExpImpl::IrregexpExecRaw(regexp_,
56                                                  subject_,
57                                                  last_end_index,
58                                                  register_array_,
59                                                  register_array_size_);
60     }
61 
62     if (num_matches_ <= 0) return NULL;
63     current_match_index_ = 0;
64     return register_array_;
65   } else {
66     return &register_array_[current_match_index_ * registers_per_match_];
67   }
68 }
69 
70 
LastSuccessfulMatch()71 int32_t* RegExpImpl::GlobalCache::LastSuccessfulMatch() {
72   int index = current_match_index_ * registers_per_match_;
73   if (num_matches_ == 0) {
74     // After a failed match we shift back by one result.
75     index -= registers_per_match_;
76   }
77   return &register_array_[index];
78 }
79 
80 
81 } }  // namespace v8::internal
82 
83 #endif  // V8_JSREGEXP_INL_H_
84