1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2008-2009 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ast.h"
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "bytecodes-irregexp.h"
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "regexp-macro-assembler.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "regexp-macro-assembler-irregexp.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "regexp-macro-assembler-irregexp-inl.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#ifdef V8_INTERPRETED_REGEXP
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpMacroAssemblerIrregexp::RegExpMacroAssemblerIrregexp(Vector<byte> buffer)
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    : buffer_(buffer),
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      pc_(0),
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      own_buffer_(false),
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      advance_current_end_(kInvalidPC) {
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpMacroAssemblerIrregexp::~RegExpMacroAssemblerIrregexp() {
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (backtrack_.is_linked()) backtrack_.Unuse();
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (own_buffer_) buffer_.Dispose();
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpMacroAssemblerIrregexp::IrregexpImplementation
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegExpMacroAssemblerIrregexp::Implementation() {
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return kBytecodeImplementation;
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::Bind(Label* l) {
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  advance_current_end_ = kInvalidPC;
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!l->is_bound());
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (l->is_linked()) {
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int pos = l->pos();
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    while (pos != 0) {
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      int fixup = pos;
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      pos = *reinterpret_cast<int32_t*>(buffer_.start() + fixup);
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      *reinterpret_cast<uint32_t*>(buffer_.start() + fixup) = pc_;
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  l->bind_to(pc_);
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::EmitOrLink(Label* l) {
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (l == NULL) l = &backtrack_;
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (l->is_bound()) {
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit32(l->pos());
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int pos = 0;
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (l->is_linked()) {
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      pos = l->pos();
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    l->link_to(pc_);
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit32(pos);
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::PopRegister(int register_index) {
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index >= 0);
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index <= kMaxRegister);
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_POP_REGISTER, register_index);
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::PushRegister(
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int register_index,
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    StackCheckFlag check_stack_limit) {
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index >= 0);
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index <= kMaxRegister);
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_PUSH_REGISTER, register_index);
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::WriteCurrentPositionToRegister(
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int register_index, int cp_offset) {
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index >= 0);
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index <= kMaxRegister);
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_SET_REGISTER_TO_CP, register_index);
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit32(cp_offset);  // Current position offset.
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::ClearRegisters(int reg_from, int reg_to) {
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(reg_from <= reg_to);
118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int reg = reg_from; reg <= reg_to; reg++) {
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    SetRegister(reg, -1);
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::ReadCurrentPositionFromRegister(
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int register_index) {
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index >= 0);
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index <= kMaxRegister);
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_SET_CP_TO_REGISTER, register_index);
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::WriteStackPointerToRegister(
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int register_index) {
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index >= 0);
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index <= kMaxRegister);
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_SET_REGISTER_TO_SP, register_index);
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::ReadStackPointerFromRegister(
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int register_index) {
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index >= 0);
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index <= kMaxRegister);
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_SET_SP_TO_REGISTER, register_index);
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
148f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochvoid RegExpMacroAssemblerIrregexp::SetCurrentPositionFromEnd(int by) {
149f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  ASSERT(is_uint24(by));
150f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  Emit(BC_SET_CURRENT_POSITION_FROM_END, by);
151f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
152f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
153f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::SetRegister(int register_index, int to) {
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index >= 0);
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index <= kMaxRegister);
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_SET_REGISTER, register_index);
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit32(to);
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::AdvanceRegister(int register_index, int by) {
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index >= 0);
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index <= kMaxRegister);
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_ADVANCE_REGISTER, register_index);
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit32(by);
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::PopCurrentPosition() {
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_POP_CP, 0);
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::PushCurrentPosition() {
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_PUSH_CP, 0);
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::Backtrack() {
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_POP_BT, 0);
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::GoTo(Label* l) {
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (advance_current_end_ == pc_) {
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Combine advance current and goto.
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    pc_ = advance_current_start_;
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit(BC_ADVANCE_CP_AND_GOTO, advance_current_offset_);
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    EmitOrLink(l);
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    advance_current_end_ = kInvalidPC;
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Regular goto.
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit(BC_GOTO, 0);
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    EmitOrLink(l);
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::PushBacktrack(Label* l) {
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_PUSH_BT, 0);
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(l);
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::Succeed() {
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_SUCCEED, 0);
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::Fail() {
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_FAIL, 0);
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::AdvanceCurrentPosition(int by) {
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(by >= kMinCPOffset);
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(by <= kMaxCPOffset);
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  advance_current_start_ = pc_;
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  advance_current_offset_ = by;
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_ADVANCE_CP, by);
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  advance_current_end_ = pc_;
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckGreedyLoop(
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Label* on_tos_equals_current_position) {
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_CHECK_GREEDY, 0);
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_tos_equals_current_position);
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::LoadCurrentCharacter(int cp_offset,
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                        Label* on_failure,
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                        bool check_bounds,
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                        int characters) {
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(cp_offset >= kMinCPOffset);
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(cp_offset <= kMaxCPOffset);
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int bytecode;
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (check_bounds) {
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (characters == 4) {
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      bytecode = BC_LOAD_4_CURRENT_CHARS;
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else if (characters == 2) {
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      bytecode = BC_LOAD_2_CURRENT_CHARS;
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ASSERT(characters == 1);
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      bytecode = BC_LOAD_CURRENT_CHAR;
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (characters == 4) {
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      bytecode = BC_LOAD_4_CURRENT_CHARS_UNCHECKED;
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else if (characters == 2) {
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      bytecode = BC_LOAD_2_CURRENT_CHARS_UNCHECKED;
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ASSERT(characters == 1);
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      bytecode = BC_LOAD_CURRENT_CHAR_UNCHECKED;
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(bytecode, cp_offset);
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (check_bounds) EmitOrLink(on_failure);
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckCharacterLT(uc16 limit,
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                    Label* on_less) {
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_CHECK_LT, limit);
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_less);
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckCharacterGT(uc16 limit,
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                    Label* on_greater) {
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_CHECK_GT, limit);
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_greater);
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckCharacter(uint32_t c, Label* on_equal) {
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (c > MAX_FIRST_ARG) {
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit(BC_CHECK_4_CHARS, 0);
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit32(c);
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit(BC_CHECK_CHAR, c);
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_equal);
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckAtStart(Label* on_at_start) {
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_CHECK_AT_START, 0);
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_at_start);
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckNotAtStart(Label* on_not_at_start) {
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_CHECK_NOT_AT_START, 0);
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_not_at_start);
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckNotCharacter(uint32_t c,
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                     Label* on_not_equal) {
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (c > MAX_FIRST_ARG) {
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit(BC_CHECK_NOT_4_CHARS, 0);
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit32(c);
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit(BC_CHECK_NOT_CHAR, c);
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_not_equal);
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckCharacterAfterAnd(
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t c,
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t mask,
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Label* on_equal) {
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (c > MAX_FIRST_ARG) {
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit(BC_AND_CHECK_4_CHARS, 0);
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit32(c);
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit(BC_AND_CHECK_CHAR, c);
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit32(mask);
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_equal);
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterAnd(
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t c,
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uint32_t mask,
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Label* on_not_equal) {
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (c > MAX_FIRST_ARG) {
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit(BC_AND_CHECK_NOT_4_CHARS, 0);
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit32(c);
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit(BC_AND_CHECK_NOT_CHAR, c);
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit32(mask);
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_not_equal);
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterMinusAnd(
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uc16 c,
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uc16 minus,
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    uc16 mask,
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Label* on_not_equal) {
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_MINUS_AND_CHECK_NOT_CHAR, c);
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit16(minus);
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit16(mask);
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_not_equal);
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckNotBackReference(int start_reg,
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                         Label* on_not_equal) {
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(start_reg >= 0);
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(start_reg <= kMaxRegister);
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_CHECK_NOT_BACK_REF, start_reg);
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_not_equal);
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckNotBackReferenceIgnoreCase(
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int start_reg,
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Label* on_not_equal) {
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(start_reg >= 0);
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(start_reg <= kMaxRegister);
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_CHECK_NOT_BACK_REF_NO_CASE, start_reg);
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_not_equal);
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckNotRegistersEqual(int reg1,
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                          int reg2,
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                          Label* on_not_equal) {
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(reg1 >= 0);
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(reg1 <= kMaxRegister);
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_CHECK_NOT_REGS_EQUAL, reg1);
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit32(reg2);
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_not_equal);
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::CheckCharacters(
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Vector<const uc16> str,
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int cp_offset,
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Label* on_failure,
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool check_end_of_string) {
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(cp_offset >= kMinCPOffset);
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(cp_offset + str.length() - 1 <= kMaxCPOffset);
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // It is vital that this loop is backwards due to the unchecked character
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // load below.
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = str.length() - 1; i >= 0; i--) {
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (check_end_of_string && i == str.length() - 1) {
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Emit(BC_LOAD_CURRENT_CHAR, cp_offset + i);
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      EmitOrLink(on_failure);
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Emit(BC_LOAD_CURRENT_CHAR_UNCHECKED, cp_offset + i);
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Emit(BC_CHECK_NOT_CHAR, str[i]);
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    EmitOrLink(on_failure);
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::IfRegisterLT(int register_index,
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                int comparand,
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                Label* on_less_than) {
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index >= 0);
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index <= kMaxRegister);
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_CHECK_REGISTER_LT, register_index);
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit32(comparand);
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_less_than);
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::IfRegisterGE(int register_index,
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                int comparand,
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                Label* on_greater_or_equal) {
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index >= 0);
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index <= kMaxRegister);
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_CHECK_REGISTER_GE, register_index);
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit32(comparand);
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_greater_or_equal);
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::IfRegisterEqPos(int register_index,
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                   Label* on_eq) {
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index >= 0);
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(register_index <= kMaxRegister);
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_CHECK_REGISTER_EQ_POS, register_index);
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EmitOrLink(on_eq);
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
438053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve BlockHandle<HeapObject> RegExpMacroAssemblerIrregexp::GetCode(
439053d10c438f14580aaf4ab1b2aad93a5a4fe8b82Steve Block    Handle<String> source) {
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Bind(&backtrack_);
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Emit(BC_POP_BT, 0);
44244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<ByteArray> array = FACTORY->NewByteArray(length());
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Copy(array->GetDataStartAddress());
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return array;
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint RegExpMacroAssemblerIrregexp::length() {
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return pc_;
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::Copy(Address a) {
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  memcpy(a, buffer_.start(), length());
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegExpMacroAssemblerIrregexp::Expand() {
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool old_buffer_was_our_own = own_buffer_;
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Vector<byte> old_buffer = buffer_;
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  buffer_ = Vector<byte>::New(old_buffer.length() * 2);
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  own_buffer_ = true;
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  memcpy(buffer_.start(), old_buffer.start(), old_buffer.length());
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (old_buffer_was_our_own) {
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    old_buffer.Dispose();
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#endif  // V8_INTERPRETED_REGEXP
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
472