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