Home | History | Annotate | Download | only in regexp
      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 
     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 
     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 
     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