1ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org// Copyright 2011 the V8 project authors. All rights reserved.
2a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Redistribution and use in source and binary forms, with or without
3a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// modification, are permitted provided that the following conditions are
4a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// met:
5a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//
6a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//     * Redistributions of source code must retain the above copyright
7a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//       notice, this list of conditions and the following disclaimer.
8a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//     * Redistributions in binary form must reproduce the above
9a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//       copyright notice, this list of conditions and the following
10a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//       disclaimer in the documentation and/or other materials provided
11a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//       with the distribution.
12a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//     * Neither the name of Google Inc. nor the names of its
13a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//       contributors may be used to endorse or promote products derived
14a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//       from this software without specific prior written permission.
15a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//
16a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
28a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// A simple interpreter for the Irregexp byte code.
29a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
30a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
31a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "v8.h"
32a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "unicode.h"
33a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "utils.h"
34a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "ast.h"
35a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "bytecodes-irregexp.h"
36a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#include "interpreter-irregexp.h"
371456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#include "jsregexp.h"
381456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#include "regexp-macro-assembler.h"
39a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
4071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
4171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
42a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
43a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
44ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgtypedef unibrow::Mapping<unibrow::Ecma262Canonicalize> Canonicalize;
45a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
46ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic bool BackRefMatchesNoCase(Canonicalize* interp_canonicalize,
47ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                 int from,
48a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                 int current,
49a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                 int len,
50a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                 Vector<const uc16> subject) {
51a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  for (int i = 0; i < len; i++) {
52a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    unibrow::uchar old_char = subject[from++];
53a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    unibrow::uchar new_char = subject[current++];
54a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    if (old_char == new_char) continue;
55e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org    unibrow::uchar old_string[1] = { old_char };
56e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org    unibrow::uchar new_string[1] = { new_char };
57ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    interp_canonicalize->get(old_char, '\0', old_string);
58ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    interp_canonicalize->get(new_char, '\0', new_string);
59e959c18cf7193e2f021245584a3c8f1f32f82c92kasperl@chromium.org    if (old_string[0] != new_string[0]) {
60a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      return false;
61a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
62a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
63a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  return true;
64a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
65a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
66a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
67ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic bool BackRefMatchesNoCase(Canonicalize* interp_canonicalize,
68ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                 int from,
698bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                                 int current,
708bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                                 int len,
7159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                                 Vector<const uint8_t> subject) {
728bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  for (int i = 0; i < len; i++) {
738bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    unsigned int old_char = subject[from++];
748bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    unsigned int new_char = subject[current++];
758bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    if (old_char == new_char) continue;
76f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // Convert both characters to lower case.
77f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    old_char |= 0x20;
78f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    new_char |= 0x20;
798bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    if (old_char != new_char) return false;
80f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    // Not letters in the ASCII range and Latin-1 range.
81f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    if (!(old_char - 'a' <= 'z' - 'a') &&
82f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org        !(old_char - 224 <= 254 - 224 && old_char != 247)) {
83f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org      return false;
84f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org    }
858bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
868bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  return true;
878bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org}
888bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
898bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
90a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#ifdef DEBUG
91a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgstatic void TraceInterpreter(const byte* code_base,
92a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                             const byte* pc,
93a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                             int stack_depth,
94a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                             int current_position,
9537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                             uint32_t current_char,
96a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                             int bytecode_length,
97a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                             const char* bytecode_name) {
98a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (FLAG_trace_regexp_bytecodes) {
9937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    bool printable = (current_char < 127 && current_char >= 32);
10037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    const char* format =
10137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        printable ?
10237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        "pc = %02x, sp = %d, curpos = %d, curchar = %08x (%c), bc = %s" :
10337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        "pc = %02x, sp = %d, curpos = %d, curchar = %08x .%c., bc = %s";
10437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    PrintF(format,
105a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org           pc - code_base,
106a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org           stack_depth,
107a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org           current_position,
10837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com           current_char,
10937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com           printable ? current_char : '.',
110a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org           bytecode_name);
111ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    for (int i = 0; i < bytecode_length; i++) {
112a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      printf(", %02x", pc[i]);
113a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
11437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    printf(" ");
11537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    for (int i = 1; i < bytecode_length; i++) {
11637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      unsigned char b = pc[i];
11737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      if (b < 127 && b >= 32) {
11837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        printf("%c", b);
11937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      } else {
12037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        printf(".");
12137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      }
12237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com    }
123a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    printf("\n");
124a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
125a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
126a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
127a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
128c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org#define BYTECODE(name)                                                      \
129c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org  case BC_##name:                                                           \
130c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org    TraceInterpreter(code_base,                                             \
131c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     pc,                                                    \
132c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     static_cast<int>(backtrack_sp - backtrack_stack_base), \
133c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     current,                                               \
134c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     current_char,                                          \
135c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org                     BC_##name##_LENGTH,                                    \
136a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                     #name);
137a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#else
138c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org#define BYTECODE(name)                                                      \
139a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  case BC_##name:
140a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif
141a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
142a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
143ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgstatic int32_t Load32Aligned(const byte* pc) {
1449085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  ASSERT((reinterpret_cast<intptr_t>(pc) & 3) == 0);
145ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  return *reinterpret_cast<const int32_t *>(pc);
146ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org}
147ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
148ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
149ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgstatic int32_t Load16Aligned(const byte* pc) {
1509085a016223a6b72bf580d5781c93ec7b9e54422ager@chromium.org  ASSERT((reinterpret_cast<intptr_t>(pc) & 1) == 0);
151ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  return *reinterpret_cast<const uint16_t *>(pc);
152ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org}
153ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org
154a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
15586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org// A simple abstraction over the backtracking stack used by the interpreter.
15686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org// This backtracking stack does not grow automatically, but it ensures that the
15786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org// the memory held by the stack is released or remembered in a cache if the
15886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org// matching terminates.
15986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.orgclass BacktrackStack {
16086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org public:
161ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  explicit BacktrackStack(Isolate* isolate) : isolate_(isolate) {
162ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (isolate->irregexp_interpreter_backtrack_stack_cache() != NULL) {
16386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      // If the cache is not empty reuse the previously allocated stack.
164ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      data_ = isolate->irregexp_interpreter_backtrack_stack_cache();
165ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate->set_irregexp_interpreter_backtrack_stack_cache(NULL);
16686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    } else {
16786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      // Cache was empty. Allocate a new backtrack stack.
16886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      data_ = NewArray<int>(kBacktrackStackSize);
16986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    }
17086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  }
17186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
17286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  ~BacktrackStack() {
173ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    if (isolate_->irregexp_interpreter_backtrack_stack_cache() == NULL) {
17486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      // The cache is empty. Keep this backtrack stack around.
175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      isolate_->set_irregexp_interpreter_backtrack_stack_cache(data_);
17686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    } else {
17786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      // A backtrack stack was already cached, just release this one.
17886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org      DeleteArray(data_);
17986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org    }
18086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  }
18186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
18286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  int* data() const { return data_; }
18386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
18486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  int max_size() const { return kBacktrackStackSize; }
18586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
18686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org private:
18786f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  static const int kBacktrackStackSize = 10000;
18886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
18986f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  int* data_;
190ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate_;
19186f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
19286f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  DISALLOW_COPY_AND_ASSIGN(BacktrackStack);
19386f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org};
19486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
19586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org
1968bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgtemplate <typename Char>
197394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comstatic RegExpImpl::IrregexpResult RawMatch(Isolate* isolate,
198394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                           const byte* code_base,
199394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                           Vector<const Char> subject,
200394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                           int* registers,
201394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                           int current,
202394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                           uint32_t current_char) {
203a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  const byte* pc = code_base;
20486f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // BacktrackStack ensures that the memory allocated for the backtracking stack
20586f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // is returned to the system or cached if there is no stack being cached at
20686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  // the moment.
207ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  BacktrackStack backtrack_stack(isolate);
20886f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  int* backtrack_stack_base = backtrack_stack.data();
2092abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org  int* backtrack_sp = backtrack_stack_base;
21086f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org  int backtrack_stack_space = backtrack_stack.max_size();
211a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#ifdef DEBUG
212a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  if (FLAG_trace_regexp_bytecodes) {
213a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    PrintF("\n\nStart bytecode interpreter\n\n");
214a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
215a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif
216a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  while (true) {
217ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    int32_t insn = Load32Aligned(pc);
218ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org    switch (insn & BYTECODE_MASK) {
219a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(BREAK)
220a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        UNREACHABLE();
221394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        return RegExpImpl::RE_FAILURE;
222a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(PUSH_CP)
223a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (--backtrack_stack_space < 0) {
224394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          return RegExpImpl::RE_EXCEPTION;
225a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
226ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        *backtrack_sp++ = current;
227a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_PUSH_CP_LENGTH;
228a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
229a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(PUSH_BT)
230a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (--backtrack_stack_space < 0) {
231394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          return RegExpImpl::RE_EXCEPTION;
232a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
233ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        *backtrack_sp++ = Load32Aligned(pc + 4);
234a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_PUSH_BT_LENGTH;
235a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
236a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(PUSH_REGISTER)
237a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (--backtrack_stack_space < 0) {
238394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          return RegExpImpl::RE_EXCEPTION;
239a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
240ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        *backtrack_sp++ = registers[insn >> BYTECODE_SHIFT];
241a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_PUSH_REGISTER_LENGTH;
242a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
243a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(SET_REGISTER)
244ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        registers[insn >> BYTECODE_SHIFT] = Load32Aligned(pc + 4);
245a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_SET_REGISTER_LENGTH;
246a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
247a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(ADVANCE_REGISTER)
248ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        registers[insn >> BYTECODE_SHIFT] += Load32Aligned(pc + 4);
249a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_ADVANCE_REGISTER_LENGTH;
250a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
251a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(SET_REGISTER_TO_CP)
252ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        registers[insn >> BYTECODE_SHIFT] = current + Load32Aligned(pc + 4);
253a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_SET_REGISTER_TO_CP_LENGTH;
254a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
255a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(SET_CP_TO_REGISTER)
256ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        current = registers[insn >> BYTECODE_SHIFT];
257a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_SET_CP_TO_REGISTER_LENGTH;
258a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
259a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(SET_REGISTER_TO_SP)
260c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org        registers[insn >> BYTECODE_SHIFT] =
261c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            static_cast<int>(backtrack_sp - backtrack_stack_base);
262a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_SET_REGISTER_TO_SP_LENGTH;
263a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
264a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(SET_SP_TO_REGISTER)
2652abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org        backtrack_sp = backtrack_stack_base + registers[insn >> BYTECODE_SHIFT];
26686f77b7fe492ed2bdfbf4e1147dab2f09c7d7003kasperl@chromium.org        backtrack_stack_space = backtrack_stack.max_size() -
267c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org            static_cast<int>(backtrack_sp - backtrack_stack_base);
268a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_SET_SP_TO_REGISTER_LENGTH;
269a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
270a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(POP_CP)
271a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        backtrack_stack_space++;
272a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        --backtrack_sp;
273a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        current = *backtrack_sp;
274a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_POP_CP_LENGTH;
275a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
276a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(POP_BT)
277a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        backtrack_stack_space++;
278a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        --backtrack_sp;
279a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc = code_base + *backtrack_sp;
280a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
281a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(POP_REGISTER)
282a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        backtrack_stack_space++;
283a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        --backtrack_sp;
284ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        registers[insn >> BYTECODE_SHIFT] = *backtrack_sp;
285a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_POP_REGISTER_LENGTH;
286a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
287a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(FAIL)
288394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        return RegExpImpl::RE_FAILURE;
289a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(SUCCEED)
290394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        return RegExpImpl::RE_SUCCESS;
291a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(ADVANCE_CP)
292ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        current += insn >> BYTECODE_SHIFT;
293a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_ADVANCE_CP_LENGTH;
294a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
295a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(GOTO)
296ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        pc = code_base + Load32Aligned(pc + 4);
297a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
298381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org      BYTECODE(ADVANCE_CP_AND_GOTO)
299381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org        current += insn >> BYTECODE_SHIFT;
300381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org        pc = code_base + Load32Aligned(pc + 4);
301381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org        break;
3028bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      BYTECODE(CHECK_GREEDY)
3038bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        if (current == backtrack_sp[-1]) {
3048bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          backtrack_sp--;
3058bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          backtrack_stack_space++;
306ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
3078bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        } else {
3088bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org          pc += BC_CHECK_GREEDY_LENGTH;
3098bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        }
3108bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        break;
311a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(LOAD_CURRENT_CHAR) {
312ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        int pos = current + (insn >> BYTECODE_SHIFT);
313a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (pos >= subject.length()) {
314ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
315a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
316a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          current_char = subject[pos];
317a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          pc += BC_LOAD_CURRENT_CHAR_LENGTH;
318a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
319a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
320a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
3218bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      BYTECODE(LOAD_CURRENT_CHAR_UNCHECKED) {
322ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        int pos = current + (insn >> BYTECODE_SHIFT);
3238bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        current_char = subject[pos];
3248bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        pc += BC_LOAD_CURRENT_CHAR_UNCHECKED_LENGTH;
3258bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org        break;
3268bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org      }
32737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      BYTECODE(LOAD_2_CURRENT_CHARS) {
328ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        int pos = current + (insn >> BYTECODE_SHIFT);
32937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        if (pos + 2 > subject.length()) {
330ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
33137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        } else {
33237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          Char next = subject[pos + 1];
33337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          current_char =
33437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com              (subject[pos] | (next << (kBitsPerByte * sizeof(Char))));
33537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          pc += BC_LOAD_2_CURRENT_CHARS_LENGTH;
33637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        }
33737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        break;
33837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      }
33937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      BYTECODE(LOAD_2_CURRENT_CHARS_UNCHECKED) {
340ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        int pos = current + (insn >> BYTECODE_SHIFT);
34137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        Char next = subject[pos + 1];
34237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        current_char = (subject[pos] | (next << (kBitsPerByte * sizeof(Char))));
34337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        pc += BC_LOAD_2_CURRENT_CHARS_UNCHECKED_LENGTH;
34437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        break;
34537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      }
34637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      BYTECODE(LOAD_4_CURRENT_CHARS) {
34737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        ASSERT(sizeof(Char) == 1);
348ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        int pos = current + (insn >> BYTECODE_SHIFT);
34937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        if (pos + 4 > subject.length()) {
350ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
35137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        } else {
35237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          Char next1 = subject[pos + 1];
35337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          Char next2 = subject[pos + 2];
35437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          Char next3 = subject[pos + 3];
35537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          current_char = (subject[pos] |
35637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                          (next1 << 8) |
35737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                          (next2 << 16) |
35837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                          (next3 << 24));
35937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          pc += BC_LOAD_4_CURRENT_CHARS_LENGTH;
36037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        }
36137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        break;
36237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      }
36337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      BYTECODE(LOAD_4_CURRENT_CHARS_UNCHECKED) {
36437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        ASSERT(sizeof(Char) == 1);
365ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        int pos = current + (insn >> BYTECODE_SHIFT);
36637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        Char next1 = subject[pos + 1];
36737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        Char next2 = subject[pos + 2];
36837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        Char next3 = subject[pos + 3];
36937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        current_char = (subject[pos] |
37037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                        (next1 << 8) |
37137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                        (next2 << 16) |
37237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                        (next3 << 24));
37337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        pc += BC_LOAD_4_CURRENT_CHARS_UNCHECKED_LENGTH;
37437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        break;
37537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      }
376ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      BYTECODE(CHECK_4_CHARS) {
377ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t c = Load32Aligned(pc + 4);
378ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if (c == current_char) {
379ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 8);
380ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        } else {
381ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc += BC_CHECK_4_CHARS_LENGTH;
382ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        }
383ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        break;
384ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      }
385a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(CHECK_CHAR) {
386ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t c = (insn >> BYTECODE_SHIFT);
387a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (c == current_char) {
388ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
389a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
390a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          pc += BC_CHECK_CHAR_LENGTH;
391a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
392a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
393a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
394ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      BYTECODE(CHECK_NOT_4_CHARS) {
395ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t c = Load32Aligned(pc + 4);
396ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if (c != current_char) {
397ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 8);
398ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        } else {
399ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc += BC_CHECK_NOT_4_CHARS_LENGTH;
400ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        }
401ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        break;
402ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      }
403a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(CHECK_NOT_CHAR) {
404ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t c = (insn >> BYTECODE_SHIFT);
405a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (c != current_char) {
406ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
407a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
408a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          pc += BC_CHECK_NOT_CHAR_LENGTH;
409a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
410a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
411a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
412ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      BYTECODE(AND_CHECK_4_CHARS) {
413ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t c = Load32Aligned(pc + 4);
414ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if (c == (current_char & Load32Aligned(pc + 8))) {
415ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 12);
416ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        } else {
417ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc += BC_AND_CHECK_4_CHARS_LENGTH;
418ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        }
419ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        break;
420ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      }
42137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      BYTECODE(AND_CHECK_CHAR) {
422ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t c = (insn >> BYTECODE_SHIFT);
423ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if (c == (current_char & Load32Aligned(pc + 4))) {
424ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 8);
425a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
42637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          pc += BC_AND_CHECK_CHAR_LENGTH;
427a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
428a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
429a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
430ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      BYTECODE(AND_CHECK_NOT_4_CHARS) {
431ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t c = Load32Aligned(pc + 4);
432ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if (c != (current_char & Load32Aligned(pc + 8))) {
433ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 12);
434ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        } else {
435ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc += BC_AND_CHECK_NOT_4_CHARS_LENGTH;
436ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        }
437ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        break;
438ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      }
43937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      BYTECODE(AND_CHECK_NOT_CHAR) {
440ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t c = (insn >> BYTECODE_SHIFT);
441ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if (c != (current_char & Load32Aligned(pc + 4))) {
442ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 8);
44337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        } else {
44437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          pc += BC_AND_CHECK_NOT_CHAR_LENGTH;
44537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        }
44637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        break;
44737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      }
44837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com      BYTECODE(MINUS_AND_CHECK_NOT_CHAR) {
449ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t c = (insn >> BYTECODE_SHIFT);
450ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t minus = Load16Aligned(pc + 4);
451ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t mask = Load16Aligned(pc + 6);
45237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com        if (c != ((current_char - minus) & mask)) {
453ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 8);
454a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
45537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com          pc += BC_MINUS_AND_CHECK_NOT_CHAR_LENGTH;
456a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
457a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
458a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
4591456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org      BYTECODE(CHECK_CHAR_IN_RANGE) {
4601456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        uint32_t from = Load16Aligned(pc + 4);
4611456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        uint32_t to = Load16Aligned(pc + 6);
4621456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        if (from <= current_char && current_char <= to) {
4631456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org          pc = code_base + Load32Aligned(pc + 8);
4641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        } else {
4651456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org          pc += BC_CHECK_CHAR_IN_RANGE_LENGTH;
4661456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        }
4671456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        break;
4681456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org      }
4691456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org      BYTECODE(CHECK_CHAR_NOT_IN_RANGE) {
4701456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        uint32_t from = Load16Aligned(pc + 4);
4711456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        uint32_t to = Load16Aligned(pc + 6);
4721456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        if (from > current_char || current_char > to) {
4731456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org          pc = code_base + Load32Aligned(pc + 8);
4741456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        } else {
4751456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org          pc += BC_CHECK_CHAR_NOT_IN_RANGE_LENGTH;
4761456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        }
4771456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        break;
4781456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org      }
4791456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org      BYTECODE(CHECK_BIT_IN_TABLE) {
4801456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        int mask = RegExpMacroAssembler::kTableMask;
4811456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        byte b = pc[8 + ((current_char & mask) >> kBitsPerByteLog2)];
4821456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        int bit = (current_char & (kBitsPerByte - 1));
4831456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        if ((b & (1 << bit)) != 0) {
4841456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org          pc = code_base + Load32Aligned(pc + 4);
4851456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        } else {
4861456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org          pc += BC_CHECK_BIT_IN_TABLE_LENGTH;
4871456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        }
4881456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org        break;
4891456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org      }
490a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(CHECK_LT) {
491ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t limit = (insn >> BYTECODE_SHIFT);
492a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (current_char < limit) {
493ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
494a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
495a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          pc += BC_CHECK_LT_LENGTH;
496a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
497a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
498a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
499a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(CHECK_GT) {
500ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        uint32_t limit = (insn >> BYTECODE_SHIFT);
501a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (current_char > limit) {
502ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
503a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
504a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          pc += BC_CHECK_GT_LENGTH;
505a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
506a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
507a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
508a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(CHECK_REGISTER_LT)
509ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if (registers[insn >> BYTECODE_SHIFT] < Load32Aligned(pc + 4)) {
510ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 8);
511a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
512a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          pc += BC_CHECK_REGISTER_LT_LENGTH;
513a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
514a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
515a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(CHECK_REGISTER_GE)
516ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if (registers[insn >> BYTECODE_SHIFT] >= Load32Aligned(pc + 4)) {
517ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 8);
518a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
519a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          pc += BC_CHECK_REGISTER_GE_LENGTH;
520a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
521a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5223291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org      BYTECODE(CHECK_REGISTER_EQ_POS)
523ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if (registers[insn >> BYTECODE_SHIFT] == current) {
524ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
5253291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        } else {
5263291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org          pc += BC_CHECK_REGISTER_EQ_POS_LENGTH;
5273291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        }
5283291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org        break;
529a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(CHECK_NOT_REGS_EQUAL)
530ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if (registers[insn >> BYTECODE_SHIFT] ==
531ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org            registers[Load32Aligned(pc + 4)]) {
532a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          pc += BC_CHECK_NOT_REGS_EQUAL_LENGTH;
533a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
534ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 8);
535a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
536a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
537a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(CHECK_NOT_BACK_REF) {
538ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        int from = registers[insn >> BYTECODE_SHIFT];
539ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
540a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (from < 0 || len <= 0) {
541a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          pc += BC_CHECK_NOT_BACK_REF_LENGTH;
542a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          break;
543a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
544a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (current + len > subject.length()) {
545ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
546a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          break;
547a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
548a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          int i;
549a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          for (i = 0; i < len; i++) {
550a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            if (subject[from + i] != subject[current + i]) {
551ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org              pc = code_base + Load32Aligned(pc + 4);
552a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org              break;
553a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            }
554a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          }
555a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          if (i < len) break;
556a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          current += len;
557a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
558a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        pc += BC_CHECK_NOT_BACK_REF_LENGTH;
559a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
560a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
561a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(CHECK_NOT_BACK_REF_NO_CASE) {
562ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        int from = registers[insn >> BYTECODE_SHIFT];
563ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        int len = registers[(insn >> BYTECODE_SHIFT) + 1] - from;
564a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (from < 0 || len <= 0) {
565a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          pc += BC_CHECK_NOT_BACK_REF_NO_CASE_LENGTH;
566a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          break;
567a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
568a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (current + len > subject.length()) {
569ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
570a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          break;
571a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
572ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org          if (BackRefMatchesNoCase(isolate->interp_canonicalize_mapping(),
573ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                   from, current, len, subject)) {
5748bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org            current += len;
575a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org            pc += BC_CHECK_NOT_BACK_REF_NO_CASE_LENGTH;
576a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          } else {
577ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org            pc = code_base + Load32Aligned(pc + 4);
578a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          }
579a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
580a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
581a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      }
582ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org      BYTECODE(CHECK_AT_START)
583ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        if (current == 0) {
584ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
585ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        } else {
586ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc += BC_CHECK_AT_START_LENGTH;
587ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        }
588ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org        break;
589a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      BYTECODE(CHECK_NOT_AT_START)
590a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        if (current == 0) {
591a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org          pc += BC_CHECK_NOT_AT_START_LENGTH;
592a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        } else {
593ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org          pc = code_base + Load32Aligned(pc + 4);
594a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        }
595a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
5964a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org      BYTECODE(SET_CURRENT_POSITION_FROM_END) {
5974a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org        int by = static_cast<uint32_t>(insn) >> BYTECODE_SHIFT;
5984a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org        if (subject.length() - current > by) {
5994a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org          current = subject.length() - by;
6004a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org          current_char = subject[current - 1];
6014a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org        }
6024a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org        pc += BC_SET_CURRENT_POSITION_FROM_END_LENGTH;
6034a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org        break;
6044a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org      }
605a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org      default:
606a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        UNREACHABLE();
607a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org        break;
608a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org    }
609a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  }
610a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
611a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
612a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
613394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comRegExpImpl::IrregexpResult IrregexpInterpreter::Match(
614394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Isolate* isolate,
615394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<ByteArray> code_array,
616394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    Handle<String> subject,
617394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    int* registers,
618394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    int start_position) {
619bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  ASSERT(subject->IsFlat());
620a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
62179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
622a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  const byte* code_base = code_array->GetDataStartAddress();
623a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  uc16 previous_char = '\n';
624ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  String::FlatContent subject_content = subject->GetFlatContent();
625ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org  if (subject_content.IsAscii()) {
62659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector();
6278bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    if (start_position != 0) previous_char = subject_vector[start_position - 1];
628ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return RawMatch(isolate,
629ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                    code_base,
6308bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                    subject_vector,
6318bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                    registers,
6328bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                    start_position,
6338bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                    previous_char);
6348bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  } else {
635ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    ASSERT(subject_content.IsTwoByte());
636ddd545c4c343dcf4331b9d80d2a0bdfa373a4a0fricow@chromium.org    Vector<const uc16> subject_vector = subject_content.ToUC16Vector();
6378bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org    if (start_position != 0) previous_char = subject_vector[start_position - 1];
638ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return RawMatch(isolate,
639ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                    code_base,
6408bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                    subject_vector,
6418bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                    registers,
6428bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                    start_position,
6438bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org                    previous_char);
6448bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  }
645a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org}
646a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
647a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} }  // namespace v8::internal
648