blob: 16766cab0985a1712119edf513a753495c77cc74 [file] [log] [blame]
ager@chromium.org381abbb2009-02-25 13:23:22 +00001// Copyright 2008-2009 the V8 project authors. All rights reserved.
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29#include "ast.h"
30#include "bytecodes-irregexp.h"
31#include "regexp-macro-assembler.h"
32#include "regexp-macro-assembler-irregexp.h"
33#include "regexp-macro-assembler-irregexp-inl.h"
34
35
kasperl@chromium.org71affb52009-05-26 05:44:31 +000036namespace v8 {
37namespace internal {
ager@chromium.orga74f0da2008-12-03 16:05:52 +000038
ricow@chromium.orgc9c80822010-04-21 08:22:37 +000039#ifdef V8_INTERPRETED_REGEXP
ager@chromium.orga74f0da2008-12-03 16:05:52 +000040
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000041RegExpMacroAssemblerIrregexp::RegExpMacroAssemblerIrregexp(Vector<byte> buffer,
42 Zone* zone)
43 : RegExpMacroAssembler(zone),
44 buffer_(buffer),
ager@chromium.orga74f0da2008-12-03 16:05:52 +000045 pc_(0),
ager@chromium.org381abbb2009-02-25 13:23:22 +000046 own_buffer_(false),
47 advance_current_end_(kInvalidPC) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +000048}
49
50
51RegExpMacroAssemblerIrregexp::~RegExpMacroAssemblerIrregexp() {
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +000052 if (backtrack_.is_linked()) backtrack_.Unuse();
ager@chromium.orgeadaf222009-06-16 09:43:10 +000053 if (own_buffer_) buffer_.Dispose();
ager@chromium.orga74f0da2008-12-03 16:05:52 +000054}
55
56
57RegExpMacroAssemblerIrregexp::IrregexpImplementation
58RegExpMacroAssemblerIrregexp::Implementation() {
59 return kBytecodeImplementation;
60}
61
62
63void RegExpMacroAssemblerIrregexp::Bind(Label* l) {
ager@chromium.org381abbb2009-02-25 13:23:22 +000064 advance_current_end_ = kInvalidPC;
ager@chromium.orga74f0da2008-12-03 16:05:52 +000065 ASSERT(!l->is_bound());
66 if (l->is_linked()) {
67 int pos = l->pos();
68 while (pos != 0) {
69 int fixup = pos;
ager@chromium.orgddb913d2009-01-27 10:01:48 +000070 pos = *reinterpret_cast<int32_t*>(buffer_.start() + fixup);
71 *reinterpret_cast<uint32_t*>(buffer_.start() + fixup) = pc_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +000072 }
73 }
74 l->bind_to(pc_);
75}
76
77
78void RegExpMacroAssemblerIrregexp::EmitOrLink(Label* l) {
ager@chromium.org8bb60582008-12-11 12:02:20 +000079 if (l == NULL) l = &backtrack_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +000080 if (l->is_bound()) {
81 Emit32(l->pos());
82 } else {
83 int pos = 0;
84 if (l->is_linked()) {
85 pos = l->pos();
86 }
87 l->link_to(pc_);
88 Emit32(pos);
89 }
90}
91
92
93void RegExpMacroAssemblerIrregexp::PopRegister(int register_index) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +000094 ASSERT(register_index >= 0);
95 ASSERT(register_index <= kMaxRegister);
96 Emit(BC_POP_REGISTER, register_index);
ager@chromium.orga74f0da2008-12-03 16:05:52 +000097}
98
99
ager@chromium.org32912102009-01-16 10:38:43 +0000100void RegExpMacroAssemblerIrregexp::PushRegister(
101 int register_index,
102 StackCheckFlag check_stack_limit) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000103 ASSERT(register_index >= 0);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000104 ASSERT(register_index <= kMaxRegister);
105 Emit(BC_PUSH_REGISTER, register_index);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000106}
107
108
109void RegExpMacroAssemblerIrregexp::WriteCurrentPositionToRegister(
ager@chromium.org8bb60582008-12-11 12:02:20 +0000110 int register_index, int cp_offset) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000111 ASSERT(register_index >= 0);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000112 ASSERT(register_index <= kMaxRegister);
113 Emit(BC_SET_REGISTER_TO_CP, register_index);
ager@chromium.org8bb60582008-12-11 12:02:20 +0000114 Emit32(cp_offset); // Current position offset.
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000115}
116
117
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000118void RegExpMacroAssemblerIrregexp::ClearRegisters(int reg_from, int reg_to) {
119 ASSERT(reg_from <= reg_to);
120 for (int reg = reg_from; reg <= reg_to; reg++) {
121 SetRegister(reg, -1);
122 }
ager@chromium.org32912102009-01-16 10:38:43 +0000123}
124
125
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000126void RegExpMacroAssemblerIrregexp::ReadCurrentPositionFromRegister(
127 int register_index) {
128 ASSERT(register_index >= 0);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000129 ASSERT(register_index <= kMaxRegister);
130 Emit(BC_SET_CP_TO_REGISTER, register_index);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000131}
132
133
134void RegExpMacroAssemblerIrregexp::WriteStackPointerToRegister(
135 int register_index) {
136 ASSERT(register_index >= 0);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000137 ASSERT(register_index <= kMaxRegister);
138 Emit(BC_SET_REGISTER_TO_SP, register_index);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000139}
140
141
142void RegExpMacroAssemblerIrregexp::ReadStackPointerFromRegister(
143 int register_index) {
144 ASSERT(register_index >= 0);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000145 ASSERT(register_index <= kMaxRegister);
146 Emit(BC_SET_SP_TO_REGISTER, register_index);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000147}
148
149
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000150void RegExpMacroAssemblerIrregexp::SetCurrentPositionFromEnd(int by) {
151 ASSERT(is_uint24(by));
152 Emit(BC_SET_CURRENT_POSITION_FROM_END, by);
153}
154
155
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000156void RegExpMacroAssemblerIrregexp::SetRegister(int register_index, int to) {
157 ASSERT(register_index >= 0);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000158 ASSERT(register_index <= kMaxRegister);
159 Emit(BC_SET_REGISTER, register_index);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000160 Emit32(to);
161}
162
163
164void RegExpMacroAssemblerIrregexp::AdvanceRegister(int register_index, int by) {
165 ASSERT(register_index >= 0);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000166 ASSERT(register_index <= kMaxRegister);
167 Emit(BC_ADVANCE_REGISTER, register_index);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000168 Emit32(by);
169}
170
171
172void RegExpMacroAssemblerIrregexp::PopCurrentPosition() {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000173 Emit(BC_POP_CP, 0);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000174}
175
176
177void RegExpMacroAssemblerIrregexp::PushCurrentPosition() {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000178 Emit(BC_PUSH_CP, 0);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000179}
180
181
182void RegExpMacroAssemblerIrregexp::Backtrack() {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000183 Emit(BC_POP_BT, 0);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000184}
185
186
187void RegExpMacroAssemblerIrregexp::GoTo(Label* l) {
ager@chromium.org381abbb2009-02-25 13:23:22 +0000188 if (advance_current_end_ == pc_) {
189 // Combine advance current and goto.
190 pc_ = advance_current_start_;
191 Emit(BC_ADVANCE_CP_AND_GOTO, advance_current_offset_);
192 EmitOrLink(l);
193 advance_current_end_ = kInvalidPC;
194 } else {
195 // Regular goto.
196 Emit(BC_GOTO, 0);
197 EmitOrLink(l);
198 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000199}
200
201
202void RegExpMacroAssemblerIrregexp::PushBacktrack(Label* l) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000203 Emit(BC_PUSH_BT, 0);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000204 EmitOrLink(l);
205}
206
207
mstarzinger@chromium.org15613d02012-05-23 12:04:37 +0000208bool RegExpMacroAssemblerIrregexp::Succeed() {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000209 Emit(BC_SUCCEED, 0);
mstarzinger@chromium.org15613d02012-05-23 12:04:37 +0000210 return false; // Restart matching for global regexp not supported.
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000211}
212
213
214void RegExpMacroAssemblerIrregexp::Fail() {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000215 Emit(BC_FAIL, 0);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000216}
217
218
219void RegExpMacroAssemblerIrregexp::AdvanceCurrentPosition(int by) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000220 ASSERT(by >= kMinCPOffset);
221 ASSERT(by <= kMaxCPOffset);
ager@chromium.org381abbb2009-02-25 13:23:22 +0000222 advance_current_start_ = pc_;
223 advance_current_offset_ = by;
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000224 Emit(BC_ADVANCE_CP, by);
ager@chromium.org381abbb2009-02-25 13:23:22 +0000225 advance_current_end_ = pc_;
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000226}
227
228
ager@chromium.org8bb60582008-12-11 12:02:20 +0000229void RegExpMacroAssemblerIrregexp::CheckGreedyLoop(
230 Label* on_tos_equals_current_position) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000231 Emit(BC_CHECK_GREEDY, 0);
ager@chromium.org8bb60582008-12-11 12:02:20 +0000232 EmitOrLink(on_tos_equals_current_position);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000233}
234
235
236void RegExpMacroAssemblerIrregexp::LoadCurrentCharacter(int cp_offset,
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000237 Label* on_failure,
238 bool check_bounds,
239 int characters) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000240 ASSERT(cp_offset >= kMinCPOffset);
241 ASSERT(cp_offset <= kMaxCPOffset);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000242 int bytecode;
243 if (check_bounds) {
244 if (characters == 4) {
245 bytecode = BC_LOAD_4_CURRENT_CHARS;
246 } else if (characters == 2) {
247 bytecode = BC_LOAD_2_CURRENT_CHARS;
248 } else {
249 ASSERT(characters == 1);
250 bytecode = BC_LOAD_CURRENT_CHAR;
251 }
252 } else {
253 if (characters == 4) {
254 bytecode = BC_LOAD_4_CURRENT_CHARS_UNCHECKED;
255 } else if (characters == 2) {
256 bytecode = BC_LOAD_2_CURRENT_CHARS_UNCHECKED;
257 } else {
258 ASSERT(characters == 1);
259 bytecode = BC_LOAD_CURRENT_CHAR_UNCHECKED;
260 }
261 }
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000262 Emit(bytecode, cp_offset);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000263 if (check_bounds) EmitOrLink(on_failure);
ager@chromium.org8bb60582008-12-11 12:02:20 +0000264}
265
266
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000267void RegExpMacroAssemblerIrregexp::CheckCharacterLT(uc16 limit,
268 Label* on_less) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000269 Emit(BC_CHECK_LT, limit);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000270 EmitOrLink(on_less);
271}
272
273
274void RegExpMacroAssemblerIrregexp::CheckCharacterGT(uc16 limit,
275 Label* on_greater) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000276 Emit(BC_CHECK_GT, limit);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000277 EmitOrLink(on_greater);
278}
279
280
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000281void RegExpMacroAssemblerIrregexp::CheckCharacter(uint32_t c, Label* on_equal) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000282 if (c > MAX_FIRST_ARG) {
283 Emit(BC_CHECK_4_CHARS, 0);
284 Emit32(c);
285 } else {
286 Emit(BC_CHECK_CHAR, c);
287 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000288 EmitOrLink(on_equal);
289}
290
291
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000292void RegExpMacroAssemblerIrregexp::CheckAtStart(Label* on_at_start) {
293 Emit(BC_CHECK_AT_START, 0);
294 EmitOrLink(on_at_start);
295}
296
297
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000298void RegExpMacroAssemblerIrregexp::CheckNotAtStart(Label* on_not_at_start) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000299 Emit(BC_CHECK_NOT_AT_START, 0);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000300 EmitOrLink(on_not_at_start);
301}
302
303
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000304void RegExpMacroAssemblerIrregexp::CheckNotCharacter(uint32_t c,
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000305 Label* on_not_equal) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000306 if (c > MAX_FIRST_ARG) {
307 Emit(BC_CHECK_NOT_4_CHARS, 0);
308 Emit32(c);
309 } else {
310 Emit(BC_CHECK_NOT_CHAR, c);
311 }
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000312 EmitOrLink(on_not_equal);
313}
314
315
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000316void RegExpMacroAssemblerIrregexp::CheckCharacterAfterAnd(
317 uint32_t c,
318 uint32_t mask,
319 Label* on_equal) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000320 if (c > MAX_FIRST_ARG) {
321 Emit(BC_AND_CHECK_4_CHARS, 0);
322 Emit32(c);
323 } else {
324 Emit(BC_AND_CHECK_CHAR, c);
325 }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000326 Emit32(mask);
327 EmitOrLink(on_equal);
328}
329
330
331void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterAnd(
332 uint32_t c,
333 uint32_t mask,
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000334 Label* on_not_equal) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000335 if (c > MAX_FIRST_ARG) {
336 Emit(BC_AND_CHECK_NOT_4_CHARS, 0);
337 Emit32(c);
338 } else {
339 Emit(BC_AND_CHECK_NOT_CHAR, c);
340 }
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000341 Emit32(mask);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000342 EmitOrLink(on_not_equal);
343}
344
345
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000346void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterMinusAnd(
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000347 uc16 c,
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000348 uc16 minus,
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000349 uc16 mask,
350 Label* on_not_equal) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000351 Emit(BC_MINUS_AND_CHECK_NOT_CHAR, c);
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000352 Emit16(minus);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000353 Emit16(mask);
354 EmitOrLink(on_not_equal);
355}
356
357
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000358void RegExpMacroAssemblerIrregexp::CheckCharacterInRange(
359 uc16 from,
360 uc16 to,
361 Label* on_in_range) {
362 Emit(BC_CHECK_CHAR_IN_RANGE, 0);
363 Emit16(from);
364 Emit16(to);
365 EmitOrLink(on_in_range);
366}
367
368
369void RegExpMacroAssemblerIrregexp::CheckCharacterNotInRange(
370 uc16 from,
371 uc16 to,
372 Label* on_not_in_range) {
373 Emit(BC_CHECK_CHAR_NOT_IN_RANGE, 0);
374 Emit16(from);
375 Emit16(to);
376 EmitOrLink(on_not_in_range);
377}
378
379
380void RegExpMacroAssemblerIrregexp::CheckBitInTable(
381 Handle<ByteArray> table, Label* on_bit_set) {
382 Emit(BC_CHECK_BIT_IN_TABLE, 0);
383 EmitOrLink(on_bit_set);
384 for (int i = 0; i < kTableSize; i += kBitsPerByte) {
385 int byte = 0;
386 for (int j = 0; j < kBitsPerByte; j++) {
387 if (table->get(i + j) != 0) byte |= 1 << j;
388 }
389 Emit8(byte);
390 }
391}
392
393
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000394void RegExpMacroAssemblerIrregexp::CheckNotBackReference(int start_reg,
ager@chromium.org8bb60582008-12-11 12:02:20 +0000395 Label* on_not_equal) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000396 ASSERT(start_reg >= 0);
397 ASSERT(start_reg <= kMaxRegister);
398 Emit(BC_CHECK_NOT_BACK_REF, start_reg);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000399 EmitOrLink(on_not_equal);
400}
401
402
403void RegExpMacroAssemblerIrregexp::CheckNotBackReferenceIgnoreCase(
404 int start_reg,
405 Label* on_not_equal) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000406 ASSERT(start_reg >= 0);
407 ASSERT(start_reg <= kMaxRegister);
408 Emit(BC_CHECK_NOT_BACK_REF_NO_CASE, start_reg);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000409 EmitOrLink(on_not_equal);
410}
411
412
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000413void RegExpMacroAssemblerIrregexp::CheckCharacters(
414 Vector<const uc16> str,
415 int cp_offset,
ager@chromium.org8bb60582008-12-11 12:02:20 +0000416 Label* on_failure,
417 bool check_end_of_string) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000418 ASSERT(cp_offset >= kMinCPOffset);
419 ASSERT(cp_offset + str.length() - 1 <= kMaxCPOffset);
ager@chromium.org8bb60582008-12-11 12:02:20 +0000420 // It is vital that this loop is backwards due to the unchecked character
421 // load below.
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000422 for (int i = str.length() - 1; i >= 0; i--) {
ager@chromium.org8bb60582008-12-11 12:02:20 +0000423 if (check_end_of_string && i == str.length() - 1) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000424 Emit(BC_LOAD_CURRENT_CHAR, cp_offset + i);
ager@chromium.org8bb60582008-12-11 12:02:20 +0000425 EmitOrLink(on_failure);
426 } else {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000427 Emit(BC_LOAD_CURRENT_CHAR_UNCHECKED, cp_offset + i);
ager@chromium.org8bb60582008-12-11 12:02:20 +0000428 }
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000429 Emit(BC_CHECK_NOT_CHAR, str[i]);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000430 EmitOrLink(on_failure);
431 }
432}
433
434
435void RegExpMacroAssemblerIrregexp::IfRegisterLT(int register_index,
436 int comparand,
437 Label* on_less_than) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000438 ASSERT(register_index >= 0);
439 ASSERT(register_index <= kMaxRegister);
440 Emit(BC_CHECK_REGISTER_LT, register_index);
441 Emit32(comparand);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000442 EmitOrLink(on_less_than);
443}
444
445
446void RegExpMacroAssemblerIrregexp::IfRegisterGE(int register_index,
447 int comparand,
448 Label* on_greater_or_equal) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000449 ASSERT(register_index >= 0);
450 ASSERT(register_index <= kMaxRegister);
451 Emit(BC_CHECK_REGISTER_GE, register_index);
452 Emit32(comparand);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000453 EmitOrLink(on_greater_or_equal);
454}
455
456
ager@chromium.org32912102009-01-16 10:38:43 +0000457void RegExpMacroAssemblerIrregexp::IfRegisterEqPos(int register_index,
458 Label* on_eq) {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000459 ASSERT(register_index >= 0);
460 ASSERT(register_index <= kMaxRegister);
461 Emit(BC_CHECK_REGISTER_EQ_POS, register_index);
ager@chromium.org32912102009-01-16 10:38:43 +0000462 EmitOrLink(on_eq);
463}
464
465
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000466Handle<HeapObject> RegExpMacroAssemblerIrregexp::GetCode(
467 Handle<String> source) {
ager@chromium.org8bb60582008-12-11 12:02:20 +0000468 Bind(&backtrack_);
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000469 Emit(BC_POP_BT, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000470 Handle<ByteArray> array = FACTORY->NewByteArray(length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000471 Copy(array->GetDataStartAddress());
472 return array;
473}
474
475
476int RegExpMacroAssemblerIrregexp::length() {
477 return pc_;
478}
479
480
481void RegExpMacroAssemblerIrregexp::Copy(Address a) {
482 memcpy(a, buffer_.start(), length());
483}
484
485
486void RegExpMacroAssemblerIrregexp::Expand() {
487 bool old_buffer_was_our_own = own_buffer_;
488 Vector<byte> old_buffer = buffer_;
489 buffer_ = Vector<byte>::New(old_buffer.length() * 2);
490 own_buffer_ = true;
491 memcpy(buffer_.start(), old_buffer.start(), old_buffer.length());
492 if (old_buffer_was_our_own) {
493 old_buffer.Dispose();
494 }
495}
496
ricow@chromium.orgc9c80822010-04-21 08:22:37 +0000497#endif // V8_INTERPRETED_REGEXP
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000498
499} } // namespace v8::internal