1 // Copyright 2008-2009 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "bytecodes-irregexp.h"
8 #include "regexp-macro-assembler.h"
9 #include "regexp-macro-assembler-irregexp.h"
10 #include "regexp-macro-assembler-irregexp-inl.h"
16 #ifdef V8_INTERPRETED_REGEXP
18 RegExpMacroAssemblerIrregexp::RegExpMacroAssemblerIrregexp(Vector<byte> buffer,
20 : RegExpMacroAssembler(zone),
24 advance_current_end_(kInvalidPC),
25 isolate_(zone->isolate()) { }
28 RegExpMacroAssemblerIrregexp::~RegExpMacroAssemblerIrregexp() {
29 if (backtrack_.is_linked()) backtrack_.Unuse();
30 if (own_buffer_) buffer_.Dispose();
34 RegExpMacroAssemblerIrregexp::IrregexpImplementation
35 RegExpMacroAssemblerIrregexp::Implementation() {
36 return kBytecodeImplementation;
40 void RegExpMacroAssemblerIrregexp::Bind(Label* l) {
41 advance_current_end_ = kInvalidPC;
42 ASSERT(!l->is_bound());
47 pos = *reinterpret_cast<int32_t*>(buffer_.start() + fixup);
48 *reinterpret_cast<uint32_t*>(buffer_.start() + fixup) = pc_;
55 void RegExpMacroAssemblerIrregexp::EmitOrLink(Label* l) {
56 if (l == NULL) l = &backtrack_;
70 void RegExpMacroAssemblerIrregexp::PopRegister(int register_index) {
71 ASSERT(register_index >= 0);
72 ASSERT(register_index <= kMaxRegister);
73 Emit(BC_POP_REGISTER, register_index);
77 void RegExpMacroAssemblerIrregexp::PushRegister(
79 StackCheckFlag check_stack_limit) {
80 ASSERT(register_index >= 0);
81 ASSERT(register_index <= kMaxRegister);
82 Emit(BC_PUSH_REGISTER, register_index);
86 void RegExpMacroAssemblerIrregexp::WriteCurrentPositionToRegister(
87 int register_index, int cp_offset) {
88 ASSERT(register_index >= 0);
89 ASSERT(register_index <= kMaxRegister);
90 Emit(BC_SET_REGISTER_TO_CP, register_index);
91 Emit32(cp_offset); // Current position offset.
95 void RegExpMacroAssemblerIrregexp::ClearRegisters(int reg_from, int reg_to) {
96 ASSERT(reg_from <= reg_to);
97 for (int reg = reg_from; reg <= reg_to; reg++) {
103 void RegExpMacroAssemblerIrregexp::ReadCurrentPositionFromRegister(
104 int register_index) {
105 ASSERT(register_index >= 0);
106 ASSERT(register_index <= kMaxRegister);
107 Emit(BC_SET_CP_TO_REGISTER, register_index);
111 void RegExpMacroAssemblerIrregexp::WriteStackPointerToRegister(
112 int register_index) {
113 ASSERT(register_index >= 0);
114 ASSERT(register_index <= kMaxRegister);
115 Emit(BC_SET_REGISTER_TO_SP, register_index);
119 void RegExpMacroAssemblerIrregexp::ReadStackPointerFromRegister(
120 int register_index) {
121 ASSERT(register_index >= 0);
122 ASSERT(register_index <= kMaxRegister);
123 Emit(BC_SET_SP_TO_REGISTER, register_index);
127 void RegExpMacroAssemblerIrregexp::SetCurrentPositionFromEnd(int by) {
128 ASSERT(is_uint24(by));
129 Emit(BC_SET_CURRENT_POSITION_FROM_END, by);
133 void RegExpMacroAssemblerIrregexp::SetRegister(int register_index, int to) {
134 ASSERT(register_index >= 0);
135 ASSERT(register_index <= kMaxRegister);
136 Emit(BC_SET_REGISTER, register_index);
141 void RegExpMacroAssemblerIrregexp::AdvanceRegister(int register_index, int by) {
142 ASSERT(register_index >= 0);
143 ASSERT(register_index <= kMaxRegister);
144 Emit(BC_ADVANCE_REGISTER, register_index);
149 void RegExpMacroAssemblerIrregexp::PopCurrentPosition() {
154 void RegExpMacroAssemblerIrregexp::PushCurrentPosition() {
159 void RegExpMacroAssemblerIrregexp::Backtrack() {
164 void RegExpMacroAssemblerIrregexp::GoTo(Label* l) {
165 if (advance_current_end_ == pc_) {
166 // Combine advance current and goto.
167 pc_ = advance_current_start_;
168 Emit(BC_ADVANCE_CP_AND_GOTO, advance_current_offset_);
170 advance_current_end_ = kInvalidPC;
179 void RegExpMacroAssemblerIrregexp::PushBacktrack(Label* l) {
185 bool RegExpMacroAssemblerIrregexp::Succeed() {
187 return false; // Restart matching for global regexp not supported.
191 void RegExpMacroAssemblerIrregexp::Fail() {
196 void RegExpMacroAssemblerIrregexp::AdvanceCurrentPosition(int by) {
197 ASSERT(by >= kMinCPOffset);
198 ASSERT(by <= kMaxCPOffset);
199 advance_current_start_ = pc_;
200 advance_current_offset_ = by;
201 Emit(BC_ADVANCE_CP, by);
202 advance_current_end_ = pc_;
206 void RegExpMacroAssemblerIrregexp::CheckGreedyLoop(
207 Label* on_tos_equals_current_position) {
208 Emit(BC_CHECK_GREEDY, 0);
209 EmitOrLink(on_tos_equals_current_position);
213 void RegExpMacroAssemblerIrregexp::LoadCurrentCharacter(int cp_offset,
217 ASSERT(cp_offset >= kMinCPOffset);
218 ASSERT(cp_offset <= kMaxCPOffset);
221 if (characters == 4) {
222 bytecode = BC_LOAD_4_CURRENT_CHARS;
223 } else if (characters == 2) {
224 bytecode = BC_LOAD_2_CURRENT_CHARS;
226 ASSERT(characters == 1);
227 bytecode = BC_LOAD_CURRENT_CHAR;
230 if (characters == 4) {
231 bytecode = BC_LOAD_4_CURRENT_CHARS_UNCHECKED;
232 } else if (characters == 2) {
233 bytecode = BC_LOAD_2_CURRENT_CHARS_UNCHECKED;
235 ASSERT(characters == 1);
236 bytecode = BC_LOAD_CURRENT_CHAR_UNCHECKED;
239 Emit(bytecode, cp_offset);
240 if (check_bounds) EmitOrLink(on_failure);
244 void RegExpMacroAssemblerIrregexp::CheckCharacterLT(uc16 limit,
246 Emit(BC_CHECK_LT, limit);
251 void RegExpMacroAssemblerIrregexp::CheckCharacterGT(uc16 limit,
253 Emit(BC_CHECK_GT, limit);
254 EmitOrLink(on_greater);
258 void RegExpMacroAssemblerIrregexp::CheckCharacter(uint32_t c, Label* on_equal) {
259 if (c > MAX_FIRST_ARG) {
260 Emit(BC_CHECK_4_CHARS, 0);
263 Emit(BC_CHECK_CHAR, c);
265 EmitOrLink(on_equal);
269 void RegExpMacroAssemblerIrregexp::CheckAtStart(Label* on_at_start) {
270 Emit(BC_CHECK_AT_START, 0);
271 EmitOrLink(on_at_start);
275 void RegExpMacroAssemblerIrregexp::CheckNotAtStart(Label* on_not_at_start) {
276 Emit(BC_CHECK_NOT_AT_START, 0);
277 EmitOrLink(on_not_at_start);
281 void RegExpMacroAssemblerIrregexp::CheckNotCharacter(uint32_t c,
282 Label* on_not_equal) {
283 if (c > MAX_FIRST_ARG) {
284 Emit(BC_CHECK_NOT_4_CHARS, 0);
287 Emit(BC_CHECK_NOT_CHAR, c);
289 EmitOrLink(on_not_equal);
293 void RegExpMacroAssemblerIrregexp::CheckCharacterAfterAnd(
297 if (c > MAX_FIRST_ARG) {
298 Emit(BC_AND_CHECK_4_CHARS, 0);
301 Emit(BC_AND_CHECK_CHAR, c);
304 EmitOrLink(on_equal);
308 void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterAnd(
311 Label* on_not_equal) {
312 if (c > MAX_FIRST_ARG) {
313 Emit(BC_AND_CHECK_NOT_4_CHARS, 0);
316 Emit(BC_AND_CHECK_NOT_CHAR, c);
319 EmitOrLink(on_not_equal);
323 void RegExpMacroAssemblerIrregexp::CheckNotCharacterAfterMinusAnd(
327 Label* on_not_equal) {
328 Emit(BC_MINUS_AND_CHECK_NOT_CHAR, c);
331 EmitOrLink(on_not_equal);
335 void RegExpMacroAssemblerIrregexp::CheckCharacterInRange(
338 Label* on_in_range) {
339 Emit(BC_CHECK_CHAR_IN_RANGE, 0);
342 EmitOrLink(on_in_range);
346 void RegExpMacroAssemblerIrregexp::CheckCharacterNotInRange(
349 Label* on_not_in_range) {
350 Emit(BC_CHECK_CHAR_NOT_IN_RANGE, 0);
353 EmitOrLink(on_not_in_range);
357 void RegExpMacroAssemblerIrregexp::CheckBitInTable(
358 Handle<ByteArray> table, Label* on_bit_set) {
359 Emit(BC_CHECK_BIT_IN_TABLE, 0);
360 EmitOrLink(on_bit_set);
361 for (int i = 0; i < kTableSize; i += kBitsPerByte) {
363 for (int j = 0; j < kBitsPerByte; j++) {
364 if (table->get(i + j) != 0) byte |= 1 << j;
371 void RegExpMacroAssemblerIrregexp::CheckNotBackReference(int start_reg,
372 Label* on_not_equal) {
373 ASSERT(start_reg >= 0);
374 ASSERT(start_reg <= kMaxRegister);
375 Emit(BC_CHECK_NOT_BACK_REF, start_reg);
376 EmitOrLink(on_not_equal);
380 void RegExpMacroAssemblerIrregexp::CheckNotBackReferenceIgnoreCase(
382 Label* on_not_equal) {
383 ASSERT(start_reg >= 0);
384 ASSERT(start_reg <= kMaxRegister);
385 Emit(BC_CHECK_NOT_BACK_REF_NO_CASE, start_reg);
386 EmitOrLink(on_not_equal);
390 void RegExpMacroAssemblerIrregexp::IfRegisterLT(int register_index,
392 Label* on_less_than) {
393 ASSERT(register_index >= 0);
394 ASSERT(register_index <= kMaxRegister);
395 Emit(BC_CHECK_REGISTER_LT, register_index);
397 EmitOrLink(on_less_than);
401 void RegExpMacroAssemblerIrregexp::IfRegisterGE(int register_index,
403 Label* on_greater_or_equal) {
404 ASSERT(register_index >= 0);
405 ASSERT(register_index <= kMaxRegister);
406 Emit(BC_CHECK_REGISTER_GE, register_index);
408 EmitOrLink(on_greater_or_equal);
412 void RegExpMacroAssemblerIrregexp::IfRegisterEqPos(int register_index,
414 ASSERT(register_index >= 0);
415 ASSERT(register_index <= kMaxRegister);
416 Emit(BC_CHECK_REGISTER_EQ_POS, register_index);
421 Handle<HeapObject> RegExpMacroAssemblerIrregexp::GetCode(
422 Handle<String> source) {
425 Handle<ByteArray> array = isolate_->factory()->NewByteArray(length());
426 Copy(array->GetDataStartAddress());
431 int RegExpMacroAssemblerIrregexp::length() {
436 void RegExpMacroAssemblerIrregexp::Copy(Address a) {
437 OS::MemCopy(a, buffer_.start(), length());
441 void RegExpMacroAssemblerIrregexp::Expand() {
442 bool old_buffer_was_our_own = own_buffer_;
443 Vector<byte> old_buffer = buffer_;
444 buffer_ = Vector<byte>::New(old_buffer.length() * 2);
446 OS::MemCopy(buffer_.start(), old_buffer.start(), old_buffer.length());
447 if (old_buffer_was_our_own) {
448 old_buffer.Dispose();
452 #endif // V8_INTERPRETED_REGEXP
454 } } // namespace v8::internal