blob: ca7a9fe9918630719570c68a86ac4ec9629c794c [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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/handles.h"
11#include "src/heap/heap.h"
12#include "src/objects.h"
13#include "src/regexp/jsregexp.h"
14
15namespace v8 {
16namespace internal {
17
18
19RegExpImpl::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
28int32_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];
Ben Murdoch097c5b22016-05-18 11:27:45 +010050 if (last_start_index == last_end_index) {
51 // Zero-length match. Advance by one code point.
52 last_end_index = AdvanceZeroLength(last_end_index);
53 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000054 if (last_end_index > subject_->length()) {
55 num_matches_ = 0; // Signal failed match.
56 return NULL;
57 }
58 num_matches_ = RegExpImpl::IrregexpExecRaw(regexp_,
59 subject_,
60 last_end_index,
61 register_array_,
62 register_array_size_);
63 }
64
65 if (num_matches_ <= 0) return NULL;
66 current_match_index_ = 0;
67 return register_array_;
68 } else {
69 return &register_array_[current_match_index_ * registers_per_match_];
70 }
71}
72
73
74int32_t* RegExpImpl::GlobalCache::LastSuccessfulMatch() {
75 int index = current_match_index_ * registers_per_match_;
76 if (num_matches_ == 0) {
77 // After a failed match we shift back by one result.
78 index -= registers_per_match_;
79 }
80 return &register_array_[index];
81}
82
83
84} // namespace internal
85} // namespace v8
86
87#endif // V8_REGEXP_JSREGEXP_INL_H_