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