Index: runtime/vm/regexp_assembler_bytecode.h |
diff --git a/runtime/vm/regexp_assembler_bytecode.h b/runtime/vm/regexp_assembler_bytecode.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2de00d01e3574aea3867846f1b334209901b3c02 |
--- /dev/null |
+++ b/runtime/vm/regexp_assembler_bytecode.h |
@@ -0,0 +1,144 @@ |
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+#ifndef VM_REGEXP_ASSEMBLER_BYTECODE_H_ |
+#define VM_REGEXP_ASSEMBLER_BYTECODE_H_ |
+ |
+#include "vm/object.h" |
+#include "vm/regexp_assembler.h" |
+ |
+namespace dart { |
+ |
+class BytecodeRegExpMacroAssembler: public RegExpMacroAssembler { |
+ public: |
+ // Create an assembler. Instructions and relocation information are emitted |
+ // into a buffer, with the instructions starting from the beginning and the |
+ // relocation information starting from the end of the buffer. See CodeDesc |
+ // for a detailed comment on the layout (globals.h). |
+ // |
+ // If the provided buffer is NULL, the assembler allocates and grows its own |
+ // buffer, and buffer_size determines the initial buffer size. The buffer is |
+ // owned by the assembler and deallocated upon destruction of the assembler. |
+ // |
+ // If the provided buffer is not NULL, the assembler uses the provided buffer |
+ // for code generation and assumes its size to be buffer_size. If the buffer |
+ // is too small, a fatal error occurs. No deallocation of the buffer is done |
+ // upon destruction of the assembler. |
+ BytecodeRegExpMacroAssembler(ZoneGrowableArray<uint8_t>* buffer, |
+ Zone* zone); |
+ virtual ~BytecodeRegExpMacroAssembler(); |
+ |
+ // The byte-code interpreter checks on each push anyway. |
+ virtual intptr_t stack_limit_slack() { return 1; } |
+ virtual bool CanReadUnaligned() { return false; } |
+ virtual void BindBlock(BlockLabel* label); |
+ virtual void AdvanceCurrentPosition(intptr_t by); // Signed cp change. |
+ virtual void PopCurrentPosition(); |
+ virtual void PushCurrentPosition(); |
+ virtual void Backtrack(); |
+ virtual void GoTo(BlockLabel* label); |
+ virtual void PushBacktrack(BlockLabel* label); |
+ virtual bool Succeed(); |
+ virtual void Fail(); |
+ virtual void PopRegister(intptr_t register_index); |
+ virtual void PushRegister(intptr_t register_index); |
+ virtual void AdvanceRegister(intptr_t reg, intptr_t by); // r[reg] += by. |
+ virtual void SetCurrentPositionFromEnd(intptr_t by); |
+ virtual void SetRegister(intptr_t register_index, intptr_t to); |
+ virtual void WriteCurrentPositionToRegister(intptr_t reg, intptr_t cp_offset); |
+ virtual void ClearRegisters(intptr_t reg_from, intptr_t reg_to); |
+ virtual void ReadCurrentPositionFromRegister(intptr_t reg); |
+ virtual void WriteStackPointerToRegister(intptr_t reg); |
+ virtual void ReadStackPointerFromRegister(intptr_t reg); |
+ virtual void LoadCurrentCharacter(intptr_t cp_offset, |
+ BlockLabel* on_end_of_input, |
+ bool check_bounds = true, |
+ intptr_t characters = 1); |
+ virtual void CheckCharacter(unsigned c, BlockLabel* on_equal); |
+ virtual void CheckCharacterAfterAnd(unsigned c, |
+ unsigned mask, |
+ BlockLabel* on_equal); |
+ virtual void CheckCharacterGT(uint16_t limit, BlockLabel* on_greater); |
+ virtual void CheckCharacterLT(uint16_t limit, BlockLabel* on_less); |
+ virtual void CheckGreedyLoop(BlockLabel* on_tos_equals_current_position); |
+ virtual void CheckAtStart(BlockLabel* on_at_start); |
+ virtual void CheckNotAtStart(BlockLabel* on_not_at_start); |
+ virtual void CheckNotCharacter(unsigned c, BlockLabel* on_not_equal); |
+ virtual void CheckNotCharacterAfterAnd(unsigned c, |
+ unsigned mask, |
+ BlockLabel* on_not_equal); |
+ virtual void CheckNotCharacterAfterMinusAnd(uint16_t c, |
+ uint16_t minus, |
+ uint16_t mask, |
+ BlockLabel* on_not_equal); |
+ virtual void CheckCharacterInRange(uint16_t from, |
+ uint16_t to, |
+ BlockLabel* on_in_range); |
+ virtual void CheckCharacterNotInRange(uint16_t from, |
+ uint16_t to, |
+ BlockLabel* on_not_in_range); |
+ virtual void CheckBitInTable(const TypedData& table, BlockLabel* on_bit_set); |
+ virtual void CheckNotBackReference(intptr_t start_reg, |
+ BlockLabel* on_no_match); |
+ virtual void CheckNotBackReferenceIgnoreCase(intptr_t start_reg, |
+ BlockLabel* on_no_match); |
+ virtual void IfRegisterLT(intptr_t register_index, |
+ intptr_t comparand, |
+ BlockLabel* if_lt); |
+ virtual void IfRegisterGE(intptr_t register_index, |
+ intptr_t comparand, |
+ BlockLabel* if_ge); |
+ virtual void IfRegisterEqPos(intptr_t register_index, BlockLabel* if_eq); |
+ |
+ virtual IrregexpImplementation Implementation(); |
+ // virtual Handle<HeapObject> GetCode(Handle<String> source); |
+ RawTypedData* GetBytecode(); |
+ |
+ // New |
+ virtual bool IsClosed() const { |
+ // Added by Dart for the IR version. Bytecode version should never need an |
+ // extra goto. |
+ return true; |
+ } |
+ virtual void Print(const char* str) { UNIMPLEMENTED(); } |
+ virtual void PrintBlocks() { UNIMPLEMENTED(); } |
+ ///// |
+ |
+ static RawInstance* Interpret(const JSRegExp& regexp, |
+ const String& str, |
+ const Smi& start_index, |
+ Zone* zone); |
+ |
+ private: |
+ void Expand(); |
+ // Code and bitmap emission. |
+ inline void EmitOrLink(BlockLabel* label); |
+ inline void Emit32(uint32_t x); |
+ inline void Emit16(uint32_t x); |
+ inline void Emit8(uint32_t x); |
+ inline void Emit(uint32_t bc, uint32_t arg); |
+ // Bytecode buffer. |
+ intptr_t length(); |
+ |
+ // The buffer into which code and relocation info are generated. |
+ ZoneGrowableArray<uint8_t>* buffer_; |
+ |
+ // The program counter. |
+ intptr_t pc_; |
+ |
+ BlockLabel backtrack_; |
+ |
+ intptr_t advance_current_start_; |
+ intptr_t advance_current_offset_; |
+ intptr_t advance_current_end_; |
+ |
+ static const int kInvalidPC = -1; |
+ |
+ DISALLOW_IMPLICIT_CONSTRUCTORS(BytecodeRegExpMacroAssembler); |
+}; |
+ |
+ |
+} // namespace dart |
+ |
+#endif // VM_REGEXP_ASSEMBLER_BYTECODE_H_ |