| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // A simple interpreter for the Irregexp byte code. | 5 // A simple interpreter for the Irregexp byte code. |
| 6 | 6 |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/ast.h" | 10 #include "src/ast.h" |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 current_char, \ | 112 current_char, \ |
| 113 BC_##name##_LENGTH, \ | 113 BC_##name##_LENGTH, \ |
| 114 #name); | 114 #name); |
| 115 #else | 115 #else |
| 116 #define BYTECODE(name) \ | 116 #define BYTECODE(name) \ |
| 117 case BC_##name: | 117 case BC_##name: |
| 118 #endif | 118 #endif |
| 119 | 119 |
| 120 | 120 |
| 121 static int32_t Load32Aligned(const byte* pc) { | 121 static int32_t Load32Aligned(const byte* pc) { |
| 122 ASSERT((reinterpret_cast<intptr_t>(pc) & 3) == 0); | 122 DCHECK((reinterpret_cast<intptr_t>(pc) & 3) == 0); |
| 123 return *reinterpret_cast<const int32_t *>(pc); | 123 return *reinterpret_cast<const int32_t *>(pc); |
| 124 } | 124 } |
| 125 | 125 |
| 126 | 126 |
| 127 static int32_t Load16Aligned(const byte* pc) { | 127 static int32_t Load16Aligned(const byte* pc) { |
| 128 ASSERT((reinterpret_cast<intptr_t>(pc) & 1) == 0); | 128 DCHECK((reinterpret_cast<intptr_t>(pc) & 1) == 0); |
| 129 return *reinterpret_cast<const uint16_t *>(pc); | 129 return *reinterpret_cast<const uint16_t *>(pc); |
| 130 } | 130 } |
| 131 | 131 |
| 132 | 132 |
| 133 // A simple abstraction over the backtracking stack used by the interpreter. | 133 // A simple abstraction over the backtracking stack used by the interpreter. |
| 134 // This backtracking stack does not grow automatically, but it ensures that the | 134 // This backtracking stack does not grow automatically, but it ensures that the |
| 135 // the memory held by the stack is released or remembered in a cache if the | 135 // the memory held by the stack is released or remembered in a cache if the |
| 136 // matching terminates. | 136 // matching terminates. |
| 137 class BacktrackStack { | 137 class BacktrackStack { |
| 138 public: | 138 public: |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 break; | 301 break; |
| 302 } | 302 } |
| 303 BYTECODE(LOAD_2_CURRENT_CHARS_UNCHECKED) { | 303 BYTECODE(LOAD_2_CURRENT_CHARS_UNCHECKED) { |
| 304 int pos = current + (insn >> BYTECODE_SHIFT); | 304 int pos = current + (insn >> BYTECODE_SHIFT); |
| 305 Char next = subject[pos + 1]; | 305 Char next = subject[pos + 1]; |
| 306 current_char = (subject[pos] | (next << (kBitsPerByte * sizeof(Char)))); | 306 current_char = (subject[pos] | (next << (kBitsPerByte * sizeof(Char)))); |
| 307 pc += BC_LOAD_2_CURRENT_CHARS_UNCHECKED_LENGTH; | 307 pc += BC_LOAD_2_CURRENT_CHARS_UNCHECKED_LENGTH; |
| 308 break; | 308 break; |
| 309 } | 309 } |
| 310 BYTECODE(LOAD_4_CURRENT_CHARS) { | 310 BYTECODE(LOAD_4_CURRENT_CHARS) { |
| 311 ASSERT(sizeof(Char) == 1); | 311 DCHECK(sizeof(Char) == 1); |
| 312 int pos = current + (insn >> BYTECODE_SHIFT); | 312 int pos = current + (insn >> BYTECODE_SHIFT); |
| 313 if (pos + 4 > subject.length()) { | 313 if (pos + 4 > subject.length()) { |
| 314 pc = code_base + Load32Aligned(pc + 4); | 314 pc = code_base + Load32Aligned(pc + 4); |
| 315 } else { | 315 } else { |
| 316 Char next1 = subject[pos + 1]; | 316 Char next1 = subject[pos + 1]; |
| 317 Char next2 = subject[pos + 2]; | 317 Char next2 = subject[pos + 2]; |
| 318 Char next3 = subject[pos + 3]; | 318 Char next3 = subject[pos + 3]; |
| 319 current_char = (subject[pos] | | 319 current_char = (subject[pos] | |
| 320 (next1 << 8) | | 320 (next1 << 8) | |
| 321 (next2 << 16) | | 321 (next2 << 16) | |
| 322 (next3 << 24)); | 322 (next3 << 24)); |
| 323 pc += BC_LOAD_4_CURRENT_CHARS_LENGTH; | 323 pc += BC_LOAD_4_CURRENT_CHARS_LENGTH; |
| 324 } | 324 } |
| 325 break; | 325 break; |
| 326 } | 326 } |
| 327 BYTECODE(LOAD_4_CURRENT_CHARS_UNCHECKED) { | 327 BYTECODE(LOAD_4_CURRENT_CHARS_UNCHECKED) { |
| 328 ASSERT(sizeof(Char) == 1); | 328 DCHECK(sizeof(Char) == 1); |
| 329 int pos = current + (insn >> BYTECODE_SHIFT); | 329 int pos = current + (insn >> BYTECODE_SHIFT); |
| 330 Char next1 = subject[pos + 1]; | 330 Char next1 = subject[pos + 1]; |
| 331 Char next2 = subject[pos + 2]; | 331 Char next2 = subject[pos + 2]; |
| 332 Char next3 = subject[pos + 3]; | 332 Char next3 = subject[pos + 3]; |
| 333 current_char = (subject[pos] | | 333 current_char = (subject[pos] | |
| 334 (next1 << 8) | | 334 (next1 << 8) | |
| 335 (next2 << 16) | | 335 (next2 << 16) | |
| 336 (next3 << 24)); | 336 (next3 << 24)); |
| 337 pc += BC_LOAD_4_CURRENT_CHARS_UNCHECKED_LENGTH; | 337 pc += BC_LOAD_4_CURRENT_CHARS_UNCHECKED_LENGTH; |
| 338 break; | 338 break; |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 } | 573 } |
| 574 } | 574 } |
| 575 | 575 |
| 576 | 576 |
| 577 RegExpImpl::IrregexpResult IrregexpInterpreter::Match( | 577 RegExpImpl::IrregexpResult IrregexpInterpreter::Match( |
| 578 Isolate* isolate, | 578 Isolate* isolate, |
| 579 Handle<ByteArray> code_array, | 579 Handle<ByteArray> code_array, |
| 580 Handle<String> subject, | 580 Handle<String> subject, |
| 581 int* registers, | 581 int* registers, |
| 582 int start_position) { | 582 int start_position) { |
| 583 ASSERT(subject->IsFlat()); | 583 DCHECK(subject->IsFlat()); |
| 584 | 584 |
| 585 DisallowHeapAllocation no_gc; | 585 DisallowHeapAllocation no_gc; |
| 586 const byte* code_base = code_array->GetDataStartAddress(); | 586 const byte* code_base = code_array->GetDataStartAddress(); |
| 587 uc16 previous_char = '\n'; | 587 uc16 previous_char = '\n'; |
| 588 String::FlatContent subject_content = subject->GetFlatContent(); | 588 String::FlatContent subject_content = subject->GetFlatContent(); |
| 589 if (subject_content.IsAscii()) { | 589 if (subject_content.IsAscii()) { |
| 590 Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector(); | 590 Vector<const uint8_t> subject_vector = subject_content.ToOneByteVector(); |
| 591 if (start_position != 0) previous_char = subject_vector[start_position - 1]; | 591 if (start_position != 0) previous_char = subject_vector[start_position - 1]; |
| 592 return RawMatch(isolate, | 592 return RawMatch(isolate, |
| 593 code_base, | 593 code_base, |
| 594 subject_vector, | 594 subject_vector, |
| 595 registers, | 595 registers, |
| 596 start_position, | 596 start_position, |
| 597 previous_char); | 597 previous_char); |
| 598 } else { | 598 } else { |
| 599 ASSERT(subject_content.IsTwoByte()); | 599 DCHECK(subject_content.IsTwoByte()); |
| 600 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); | 600 Vector<const uc16> subject_vector = subject_content.ToUC16Vector(); |
| 601 if (start_position != 0) previous_char = subject_vector[start_position - 1]; | 601 if (start_position != 0) previous_char = subject_vector[start_position - 1]; |
| 602 return RawMatch(isolate, | 602 return RawMatch(isolate, |
| 603 code_base, | 603 code_base, |
| 604 subject_vector, | 604 subject_vector, |
| 605 registers, | 605 registers, |
| 606 start_position, | 606 start_position, |
| 607 previous_char); | 607 previous_char); |
| 608 } | 608 } |
| 609 } | 609 } |
| 610 | 610 |
| 611 } } // namespace v8::internal | 611 } } // namespace v8::internal |
| OLD | NEW |