1 // Copyright 2012 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. 4 5 #ifndef V8_IA32_REGEXP_MACRO_ASSEMBLER_IA32_H_ 6 #define V8_IA32_REGEXP_MACRO_ASSEMBLER_IA32_H_ 7 8 #include "src/ia32/assembler-ia32.h" 9 #include "src/ia32/assembler-ia32-inl.h" 10 #include "src/macro-assembler.h" 11 12 namespace v8 { 13 namespace internal { 14 15 #ifndef V8_INTERPRETED_REGEXP 16 class RegExpMacroAssemblerIA32: public NativeRegExpMacroAssembler { 17 public: 18 RegExpMacroAssemblerIA32(Mode mode, int registers_to_save, Zone* zone); 19 virtual ~RegExpMacroAssemblerIA32(); 20 virtual int stack_limit_slack(); 21 virtual void AdvanceCurrentPosition(int by); 22 virtual void AdvanceRegister(int reg, int by); 23 virtual void Backtrack(); 24 virtual void Bind(Label* label); 25 virtual void CheckAtStart(Label* on_at_start); 26 virtual void CheckCharacter(uint32_t c, Label* on_equal); 27 virtual void CheckCharacterAfterAnd(uint32_t c, 28 uint32_t mask, 29 Label* on_equal); 30 virtual void CheckCharacterGT(uc16 limit, Label* on_greater); 31 virtual void CheckCharacterLT(uc16 limit, Label* on_less); 32 // A "greedy loop" is a loop that is both greedy and with a simple 33 // body. It has a particularly simple implementation. 34 virtual void CheckGreedyLoop(Label* on_tos_equals_current_position); 35 virtual void CheckNotAtStart(Label* on_not_at_start); 36 virtual void CheckNotBackReference(int start_reg, Label* on_no_match); 37 virtual void CheckNotBackReferenceIgnoreCase(int start_reg, 38 Label* on_no_match); 39 virtual void CheckNotCharacter(uint32_t c, Label* on_not_equal); 40 virtual void CheckNotCharacterAfterAnd(uint32_t c, 41 uint32_t mask, 42 Label* on_not_equal); 43 virtual void CheckNotCharacterAfterMinusAnd(uc16 c, 44 uc16 minus, 45 uc16 mask, 46 Label* on_not_equal); 47 virtual void CheckCharacterInRange(uc16 from, 48 uc16 to, 49 Label* on_in_range); 50 virtual void CheckCharacterNotInRange(uc16 from, 51 uc16 to, 52 Label* on_not_in_range); 53 virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set); 54 55 // Checks whether the given offset from the current position is before 56 // the end of the string. 57 virtual void CheckPosition(int cp_offset, Label* on_outside_input); 58 virtual bool CheckSpecialCharacterClass(uc16 type, Label* on_no_match); 59 virtual void Fail(); 60 virtual Handle<HeapObject> GetCode(Handle<String> source); 61 virtual void GoTo(Label* label); 62 virtual void IfRegisterGE(int reg, int comparand, Label* if_ge); 63 virtual void IfRegisterLT(int reg, int comparand, Label* if_lt); 64 virtual void IfRegisterEqPos(int reg, Label* if_eq); 65 virtual IrregexpImplementation Implementation(); 66 virtual void LoadCurrentCharacter(int cp_offset, 67 Label* on_end_of_input, 68 bool check_bounds = true, 69 int characters = 1); 70 virtual void PopCurrentPosition(); 71 virtual void PopRegister(int register_index); 72 virtual void PushBacktrack(Label* label); 73 virtual void PushCurrentPosition(); 74 virtual void PushRegister(int register_index, 75 StackCheckFlag check_stack_limit); 76 virtual void ReadCurrentPositionFromRegister(int reg); 77 virtual void ReadStackPointerFromRegister(int reg); 78 virtual void SetCurrentPositionFromEnd(int by); 79 virtual void SetRegister(int register_index, int to); 80 virtual bool Succeed(); 81 virtual void WriteCurrentPositionToRegister(int reg, int cp_offset); 82 virtual void ClearRegisters(int reg_from, int reg_to); 83 virtual void WriteStackPointerToRegister(int reg); 84 85 // Called from RegExp if the stack-guard is triggered. 86 // If the code object is relocated, the return address is fixed before 87 // returning. 88 static int CheckStackGuardState(Address* return_address, 89 Code* re_code, 90 Address re_frame); 91 92 private: 93 // Offsets from ebp of function parameters and stored registers. 94 static const int kFramePointer = 0; 95 // Above the frame pointer - function parameters and return address. 96 static const int kReturn_eip = kFramePointer + kPointerSize; 97 static const int kFrameAlign = kReturn_eip + kPointerSize; 98 // Parameters. 99 static const int kInputString = kFrameAlign; 100 static const int kStartIndex = kInputString + kPointerSize; 101 static const int kInputStart = kStartIndex + kPointerSize; 102 static const int kInputEnd = kInputStart + kPointerSize; 103 static const int kRegisterOutput = kInputEnd + kPointerSize; 104 // For the case of global regular expression, we have room to store at least 105 // one set of capture results. For the case of non-global regexp, we ignore 106 // this value. 107 static const int kNumOutputRegisters = kRegisterOutput + kPointerSize; 108 static const int kStackHighEnd = kNumOutputRegisters + kPointerSize; 109 static const int kDirectCall = kStackHighEnd + kPointerSize; 110 static const int kIsolate = kDirectCall + kPointerSize; 111 // Below the frame pointer - local stack variables. 112 // When adding local variables remember to push space for them in 113 // the frame in GetCode. 114 static const int kBackup_esi = kFramePointer - kPointerSize; 115 static const int kBackup_edi = kBackup_esi - kPointerSize; 116 static const int kBackup_ebx = kBackup_edi - kPointerSize; 117 static const int kSuccessfulCaptures = kBackup_ebx - kPointerSize; 118 static const int kInputStartMinusOne = kSuccessfulCaptures - kPointerSize; 119 // First register address. Following registers are below it on the stack. 120 static const int kRegisterZero = kInputStartMinusOne - kPointerSize; 121 122 // Initial size of code buffer. 123 static const size_t kRegExpCodeSize = 1024; 124 125 // Load a number of characters at the given offset from the 126 // current position, into the current-character register. 127 void LoadCurrentCharacterUnchecked(int cp_offset, int character_count); 128 129 // Check whether preemption has been requested. 130 void CheckPreemption(); 131 132 // Check whether we are exceeding the stack limit on the backtrack stack. 133 void CheckStackLimit(); 134 135 // Generate a call to CheckStackGuardState. 136 void CallCheckStackGuardState(Register scratch); 137 138 // The ebp-relative location of a regexp register. 139 Operand register_location(int register_index); 140 141 // The register containing the current character after LoadCurrentCharacter. current_character()142 inline Register current_character() { return edx; } 143 144 // The register containing the backtrack stack top. Provides a meaningful 145 // name to the register. backtrack_stackpointer()146 inline Register backtrack_stackpointer() { return ecx; } 147 148 // Byte size of chars in the string to match (decided by the Mode argument) char_size()149 inline int char_size() { return static_cast<int>(mode_); } 150 151 // Equivalent to a conditional branch to the label, unless the label 152 // is NULL, in which case it is a conditional Backtrack. 153 void BranchOrBacktrack(Condition condition, Label* to); 154 155 // Call and return internally in the generated code in a way that 156 // is GC-safe (i.e., doesn't leave absolute code addresses on the stack) 157 inline void SafeCall(Label* to); 158 inline void SafeReturn(); 159 inline void SafeCallTarget(Label* name); 160 161 // Pushes the value of a register on the backtrack stack. Decrements the 162 // stack pointer (ecx) by a word size and stores the register's value there. 163 inline void Push(Register source); 164 165 // Pushes a value on the backtrack stack. Decrements the stack pointer (ecx) 166 // by a word size and stores the value there. 167 inline void Push(Immediate value); 168 169 // Pops a value from the backtrack stack. Reads the word at the stack pointer 170 // (ecx) and increments it by a word size. 171 inline void Pop(Register target); 172 isolate()173 Isolate* isolate() const { return masm_->isolate(); } 174 175 MacroAssembler* masm_; 176 177 // Which mode to generate code for (LATIN1 or UC16). 178 Mode mode_; 179 180 // One greater than maximal register index actually used. 181 int num_registers_; 182 183 // Number of registers to output at the end (the saved registers 184 // are always 0..num_saved_registers_-1) 185 int num_saved_registers_; 186 187 // Labels used internally. 188 Label entry_label_; 189 Label start_label_; 190 Label success_label_; 191 Label backtrack_label_; 192 Label exit_label_; 193 Label check_preempt_label_; 194 Label stack_overflow_label_; 195 }; 196 #endif // V8_INTERPRETED_REGEXP 197 198 }} // namespace v8::internal 199 200 #endif // V8_IA32_REGEXP_MACRO_ASSEMBLER_IA32_H_ 201