OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/regexp_assembler_bytecode.h" | 5 #include "vm/regexp_assembler_bytecode.h" |
6 | 6 |
7 #include "vm/regexp_assembler_bytecode_inl.h" | |
8 #include "vm/exceptions.h" | 7 #include "vm/exceptions.h" |
9 #include "vm/object_store.h" | 8 #include "vm/object_store.h" |
| 9 #include "vm/regexp.h" |
| 10 #include "vm/regexp_assembler.h" |
| 11 #include "vm/regexp_assembler_bytecode_inl.h" |
10 #include "vm/regexp_bytecodes.h" | 12 #include "vm/regexp_bytecodes.h" |
11 #include "vm/regexp_assembler.h" | 13 #include "vm/regexp_interpreter.h" |
12 #include "vm/regexp.h" | |
13 #include "vm/regexp_parser.h" | 14 #include "vm/regexp_parser.h" |
14 #include "vm/regexp_interpreter.h" | |
15 #include "vm/timeline.h" | 15 #include "vm/timeline.h" |
16 | 16 |
17 namespace dart { | 17 namespace dart { |
18 | 18 |
19 BytecodeRegExpMacroAssembler::BytecodeRegExpMacroAssembler( | 19 BytecodeRegExpMacroAssembler::BytecodeRegExpMacroAssembler( |
20 ZoneGrowableArray<uint8_t>* buffer, | 20 ZoneGrowableArray<uint8_t>* buffer, |
21 Zone* zone) | 21 Zone* zone) |
22 : RegExpMacroAssembler(zone), | 22 : RegExpMacroAssembler(zone), |
23 buffer_(buffer), | 23 buffer_(buffer), |
24 pc_(0), | 24 pc_(0), |
25 advance_current_end_(kInvalidPC) {} | 25 advance_current_end_(kInvalidPC) {} |
26 | 26 |
27 | |
28 BytecodeRegExpMacroAssembler::~BytecodeRegExpMacroAssembler() { | 27 BytecodeRegExpMacroAssembler::~BytecodeRegExpMacroAssembler() { |
29 if (backtrack_.is_linked()) backtrack_.Unuse(); | 28 if (backtrack_.is_linked()) backtrack_.Unuse(); |
30 } | 29 } |
31 | 30 |
32 | |
33 BytecodeRegExpMacroAssembler::IrregexpImplementation | 31 BytecodeRegExpMacroAssembler::IrregexpImplementation |
34 BytecodeRegExpMacroAssembler::Implementation() { | 32 BytecodeRegExpMacroAssembler::Implementation() { |
35 return kBytecodeImplementation; | 33 return kBytecodeImplementation; |
36 } | 34 } |
37 | 35 |
38 | |
39 void BytecodeRegExpMacroAssembler::BindBlock(BlockLabel* l) { | 36 void BytecodeRegExpMacroAssembler::BindBlock(BlockLabel* l) { |
40 advance_current_end_ = kInvalidPC; | 37 advance_current_end_ = kInvalidPC; |
41 ASSERT(!l->is_bound()); | 38 ASSERT(!l->is_bound()); |
42 if (l->is_linked()) { | 39 if (l->is_linked()) { |
43 intptr_t pos = l->pos(); | 40 intptr_t pos = l->pos(); |
44 while (pos != 0) { | 41 while (pos != 0) { |
45 intptr_t fixup = pos; | 42 intptr_t fixup = pos; |
46 pos = *reinterpret_cast<int32_t*>(buffer_->data() + fixup); | 43 pos = *reinterpret_cast<int32_t*>(buffer_->data() + fixup); |
47 *reinterpret_cast<uint32_t*>(buffer_->data() + fixup) = pc_; | 44 *reinterpret_cast<uint32_t*>(buffer_->data() + fixup) = pc_; |
48 } | 45 } |
49 } | 46 } |
50 l->bind_to(pc_); | 47 l->bind_to(pc_); |
51 } | 48 } |
52 | 49 |
53 | |
54 void BytecodeRegExpMacroAssembler::EmitOrLink(BlockLabel* l) { | 50 void BytecodeRegExpMacroAssembler::EmitOrLink(BlockLabel* l) { |
55 if (l == NULL) l = &backtrack_; | 51 if (l == NULL) l = &backtrack_; |
56 if (l->is_bound()) { | 52 if (l->is_bound()) { |
57 Emit32(l->pos()); | 53 Emit32(l->pos()); |
58 } else { | 54 } else { |
59 int pos = 0; | 55 int pos = 0; |
60 if (l->is_linked()) { | 56 if (l->is_linked()) { |
61 pos = l->pos(); | 57 pos = l->pos(); |
62 } | 58 } |
63 l->link_to(pc_); | 59 l->link_to(pc_); |
64 Emit32(pos); | 60 Emit32(pos); |
65 } | 61 } |
66 } | 62 } |
67 | 63 |
68 | |
69 void BytecodeRegExpMacroAssembler::PopRegister(intptr_t register_index) { | 64 void BytecodeRegExpMacroAssembler::PopRegister(intptr_t register_index) { |
70 ASSERT(register_index >= 0); | 65 ASSERT(register_index >= 0); |
71 ASSERT(register_index <= kMaxRegister); | 66 ASSERT(register_index <= kMaxRegister); |
72 Emit(BC_POP_REGISTER, register_index); | 67 Emit(BC_POP_REGISTER, register_index); |
73 } | 68 } |
74 | 69 |
75 | |
76 void BytecodeRegExpMacroAssembler::PushRegister(intptr_t register_index) { | 70 void BytecodeRegExpMacroAssembler::PushRegister(intptr_t register_index) { |
77 ASSERT(register_index >= 0); | 71 ASSERT(register_index >= 0); |
78 ASSERT(register_index <= kMaxRegister); | 72 ASSERT(register_index <= kMaxRegister); |
79 Emit(BC_PUSH_REGISTER, register_index); | 73 Emit(BC_PUSH_REGISTER, register_index); |
80 } | 74 } |
81 | 75 |
82 | |
83 void BytecodeRegExpMacroAssembler::WriteCurrentPositionToRegister( | 76 void BytecodeRegExpMacroAssembler::WriteCurrentPositionToRegister( |
84 intptr_t register_index, | 77 intptr_t register_index, |
85 intptr_t cp_offset) { | 78 intptr_t cp_offset) { |
86 ASSERT(register_index >= 0); | 79 ASSERT(register_index >= 0); |
87 ASSERT(register_index <= kMaxRegister); | 80 ASSERT(register_index <= kMaxRegister); |
88 Emit(BC_SET_REGISTER_TO_CP, register_index); | 81 Emit(BC_SET_REGISTER_TO_CP, register_index); |
89 Emit32(cp_offset); // Current position offset. | 82 Emit32(cp_offset); // Current position offset. |
90 } | 83 } |
91 | 84 |
92 | |
93 void BytecodeRegExpMacroAssembler::ClearRegisters(intptr_t reg_from, | 85 void BytecodeRegExpMacroAssembler::ClearRegisters(intptr_t reg_from, |
94 intptr_t reg_to) { | 86 intptr_t reg_to) { |
95 ASSERT(reg_from <= reg_to); | 87 ASSERT(reg_from <= reg_to); |
96 for (int reg = reg_from; reg <= reg_to; reg++) { | 88 for (int reg = reg_from; reg <= reg_to; reg++) { |
97 SetRegister(reg, -1); | 89 SetRegister(reg, -1); |
98 } | 90 } |
99 } | 91 } |
100 | 92 |
101 | |
102 void BytecodeRegExpMacroAssembler::ReadCurrentPositionFromRegister( | 93 void BytecodeRegExpMacroAssembler::ReadCurrentPositionFromRegister( |
103 intptr_t register_index) { | 94 intptr_t register_index) { |
104 ASSERT(register_index >= 0); | 95 ASSERT(register_index >= 0); |
105 ASSERT(register_index <= kMaxRegister); | 96 ASSERT(register_index <= kMaxRegister); |
106 Emit(BC_SET_CP_TO_REGISTER, register_index); | 97 Emit(BC_SET_CP_TO_REGISTER, register_index); |
107 } | 98 } |
108 | 99 |
109 | |
110 void BytecodeRegExpMacroAssembler::WriteStackPointerToRegister( | 100 void BytecodeRegExpMacroAssembler::WriteStackPointerToRegister( |
111 intptr_t register_index) { | 101 intptr_t register_index) { |
112 ASSERT(register_index >= 0); | 102 ASSERT(register_index >= 0); |
113 ASSERT(register_index <= kMaxRegister); | 103 ASSERT(register_index <= kMaxRegister); |
114 Emit(BC_SET_REGISTER_TO_SP, register_index); | 104 Emit(BC_SET_REGISTER_TO_SP, register_index); |
115 } | 105 } |
116 | 106 |
117 | |
118 void BytecodeRegExpMacroAssembler::ReadStackPointerFromRegister( | 107 void BytecodeRegExpMacroAssembler::ReadStackPointerFromRegister( |
119 intptr_t register_index) { | 108 intptr_t register_index) { |
120 ASSERT(register_index >= 0); | 109 ASSERT(register_index >= 0); |
121 ASSERT(register_index <= kMaxRegister); | 110 ASSERT(register_index <= kMaxRegister); |
122 Emit(BC_SET_SP_TO_REGISTER, register_index); | 111 Emit(BC_SET_SP_TO_REGISTER, register_index); |
123 } | 112 } |
124 | 113 |
125 | |
126 void BytecodeRegExpMacroAssembler::SetCurrentPositionFromEnd(intptr_t by) { | 114 void BytecodeRegExpMacroAssembler::SetCurrentPositionFromEnd(intptr_t by) { |
127 ASSERT(Utils::IsUint(24, by)); | 115 ASSERT(Utils::IsUint(24, by)); |
128 Emit(BC_SET_CURRENT_POSITION_FROM_END, by); | 116 Emit(BC_SET_CURRENT_POSITION_FROM_END, by); |
129 } | 117 } |
130 | 118 |
131 | |
132 void BytecodeRegExpMacroAssembler::SetRegister(intptr_t register_index, | 119 void BytecodeRegExpMacroAssembler::SetRegister(intptr_t register_index, |
133 intptr_t to) { | 120 intptr_t to) { |
134 ASSERT(register_index >= 0); | 121 ASSERT(register_index >= 0); |
135 ASSERT(register_index <= kMaxRegister); | 122 ASSERT(register_index <= kMaxRegister); |
136 Emit(BC_SET_REGISTER, register_index); | 123 Emit(BC_SET_REGISTER, register_index); |
137 Emit32(to); | 124 Emit32(to); |
138 } | 125 } |
139 | 126 |
140 | |
141 void BytecodeRegExpMacroAssembler::AdvanceRegister(intptr_t register_index, | 127 void BytecodeRegExpMacroAssembler::AdvanceRegister(intptr_t register_index, |
142 intptr_t by) { | 128 intptr_t by) { |
143 ASSERT(register_index >= 0); | 129 ASSERT(register_index >= 0); |
144 ASSERT(register_index <= kMaxRegister); | 130 ASSERT(register_index <= kMaxRegister); |
145 Emit(BC_ADVANCE_REGISTER, register_index); | 131 Emit(BC_ADVANCE_REGISTER, register_index); |
146 Emit32(by); | 132 Emit32(by); |
147 } | 133 } |
148 | 134 |
149 | |
150 void BytecodeRegExpMacroAssembler::PopCurrentPosition() { | 135 void BytecodeRegExpMacroAssembler::PopCurrentPosition() { |
151 Emit(BC_POP_CP, 0); | 136 Emit(BC_POP_CP, 0); |
152 } | 137 } |
153 | 138 |
154 | |
155 void BytecodeRegExpMacroAssembler::PushCurrentPosition() { | 139 void BytecodeRegExpMacroAssembler::PushCurrentPosition() { |
156 Emit(BC_PUSH_CP, 0); | 140 Emit(BC_PUSH_CP, 0); |
157 } | 141 } |
158 | 142 |
159 | |
160 void BytecodeRegExpMacroAssembler::Backtrack() { | 143 void BytecodeRegExpMacroAssembler::Backtrack() { |
161 Emit(BC_POP_BT, 0); | 144 Emit(BC_POP_BT, 0); |
162 } | 145 } |
163 | 146 |
164 | |
165 void BytecodeRegExpMacroAssembler::GoTo(BlockLabel* l) { | 147 void BytecodeRegExpMacroAssembler::GoTo(BlockLabel* l) { |
166 if (advance_current_end_ == pc_) { | 148 if (advance_current_end_ == pc_) { |
167 // Combine advance current and goto. | 149 // Combine advance current and goto. |
168 pc_ = advance_current_start_; | 150 pc_ = advance_current_start_; |
169 Emit(BC_ADVANCE_CP_AND_GOTO, advance_current_offset_); | 151 Emit(BC_ADVANCE_CP_AND_GOTO, advance_current_offset_); |
170 EmitOrLink(l); | 152 EmitOrLink(l); |
171 advance_current_end_ = kInvalidPC; | 153 advance_current_end_ = kInvalidPC; |
172 } else { | 154 } else { |
173 // Regular goto. | 155 // Regular goto. |
174 Emit(BC_GOTO, 0); | 156 Emit(BC_GOTO, 0); |
175 EmitOrLink(l); | 157 EmitOrLink(l); |
176 } | 158 } |
177 } | 159 } |
178 | 160 |
179 | |
180 void BytecodeRegExpMacroAssembler::PushBacktrack(BlockLabel* l) { | 161 void BytecodeRegExpMacroAssembler::PushBacktrack(BlockLabel* l) { |
181 Emit(BC_PUSH_BT, 0); | 162 Emit(BC_PUSH_BT, 0); |
182 EmitOrLink(l); | 163 EmitOrLink(l); |
183 } | 164 } |
184 | 165 |
185 | |
186 bool BytecodeRegExpMacroAssembler::Succeed() { | 166 bool BytecodeRegExpMacroAssembler::Succeed() { |
187 Emit(BC_SUCCEED, 0); | 167 Emit(BC_SUCCEED, 0); |
188 return false; // Restart matching for global regexp not supported. | 168 return false; // Restart matching for global regexp not supported. |
189 } | 169 } |
190 | 170 |
191 | |
192 void BytecodeRegExpMacroAssembler::Fail() { | 171 void BytecodeRegExpMacroAssembler::Fail() { |
193 Emit(BC_FAIL, 0); | 172 Emit(BC_FAIL, 0); |
194 } | 173 } |
195 | 174 |
196 | |
197 void BytecodeRegExpMacroAssembler::AdvanceCurrentPosition(intptr_t by) { | 175 void BytecodeRegExpMacroAssembler::AdvanceCurrentPosition(intptr_t by) { |
198 ASSERT(by >= kMinCPOffset); | 176 ASSERT(by >= kMinCPOffset); |
199 ASSERT(by <= kMaxCPOffset); | 177 ASSERT(by <= kMaxCPOffset); |
200 advance_current_start_ = pc_; | 178 advance_current_start_ = pc_; |
201 advance_current_offset_ = by; | 179 advance_current_offset_ = by; |
202 Emit(BC_ADVANCE_CP, by); | 180 Emit(BC_ADVANCE_CP, by); |
203 advance_current_end_ = pc_; | 181 advance_current_end_ = pc_; |
204 } | 182 } |
205 | 183 |
206 | |
207 void BytecodeRegExpMacroAssembler::CheckGreedyLoop( | 184 void BytecodeRegExpMacroAssembler::CheckGreedyLoop( |
208 BlockLabel* on_tos_equals_current_position) { | 185 BlockLabel* on_tos_equals_current_position) { |
209 Emit(BC_CHECK_GREEDY, 0); | 186 Emit(BC_CHECK_GREEDY, 0); |
210 EmitOrLink(on_tos_equals_current_position); | 187 EmitOrLink(on_tos_equals_current_position); |
211 } | 188 } |
212 | 189 |
213 | |
214 void BytecodeRegExpMacroAssembler::LoadCurrentCharacter(intptr_t cp_offset, | 190 void BytecodeRegExpMacroAssembler::LoadCurrentCharacter(intptr_t cp_offset, |
215 BlockLabel* on_failure, | 191 BlockLabel* on_failure, |
216 bool check_bounds, | 192 bool check_bounds, |
217 intptr_t characters) { | 193 intptr_t characters) { |
218 ASSERT(cp_offset >= kMinCPOffset); | 194 ASSERT(cp_offset >= kMinCPOffset); |
219 ASSERT(cp_offset <= kMaxCPOffset); | 195 ASSERT(cp_offset <= kMaxCPOffset); |
220 int bytecode; | 196 int bytecode; |
221 if (check_bounds) { | 197 if (check_bounds) { |
222 if (characters == 4) { | 198 if (characters == 4) { |
223 bytecode = BC_LOAD_4_CURRENT_CHARS; | 199 bytecode = BC_LOAD_4_CURRENT_CHARS; |
(...skipping 10 matching lines...) Expand all Loading... |
234 bytecode = BC_LOAD_2_CURRENT_CHARS_UNCHECKED; | 210 bytecode = BC_LOAD_2_CURRENT_CHARS_UNCHECKED; |
235 } else { | 211 } else { |
236 ASSERT(characters == 1); | 212 ASSERT(characters == 1); |
237 bytecode = BC_LOAD_CURRENT_CHAR_UNCHECKED; | 213 bytecode = BC_LOAD_CURRENT_CHAR_UNCHECKED; |
238 } | 214 } |
239 } | 215 } |
240 Emit(bytecode, cp_offset); | 216 Emit(bytecode, cp_offset); |
241 if (check_bounds) EmitOrLink(on_failure); | 217 if (check_bounds) EmitOrLink(on_failure); |
242 } | 218 } |
243 | 219 |
244 | |
245 void BytecodeRegExpMacroAssembler::CheckCharacterLT(uint16_t limit, | 220 void BytecodeRegExpMacroAssembler::CheckCharacterLT(uint16_t limit, |
246 BlockLabel* on_less) { | 221 BlockLabel* on_less) { |
247 Emit(BC_CHECK_LT, limit); | 222 Emit(BC_CHECK_LT, limit); |
248 EmitOrLink(on_less); | 223 EmitOrLink(on_less); |
249 } | 224 } |
250 | 225 |
251 | |
252 void BytecodeRegExpMacroAssembler::CheckCharacterGT(uint16_t limit, | 226 void BytecodeRegExpMacroAssembler::CheckCharacterGT(uint16_t limit, |
253 BlockLabel* on_greater) { | 227 BlockLabel* on_greater) { |
254 Emit(BC_CHECK_GT, limit); | 228 Emit(BC_CHECK_GT, limit); |
255 EmitOrLink(on_greater); | 229 EmitOrLink(on_greater); |
256 } | 230 } |
257 | 231 |
258 | |
259 void BytecodeRegExpMacroAssembler::CheckCharacter(uint32_t c, | 232 void BytecodeRegExpMacroAssembler::CheckCharacter(uint32_t c, |
260 BlockLabel* on_equal) { | 233 BlockLabel* on_equal) { |
261 if (c > MAX_FIRST_ARG) { | 234 if (c > MAX_FIRST_ARG) { |
262 Emit(BC_CHECK_4_CHARS, 0); | 235 Emit(BC_CHECK_4_CHARS, 0); |
263 Emit32(c); | 236 Emit32(c); |
264 } else { | 237 } else { |
265 Emit(BC_CHECK_CHAR, c); | 238 Emit(BC_CHECK_CHAR, c); |
266 } | 239 } |
267 EmitOrLink(on_equal); | 240 EmitOrLink(on_equal); |
268 } | 241 } |
269 | 242 |
270 | |
271 void BytecodeRegExpMacroAssembler::CheckAtStart(BlockLabel* on_at_start) { | 243 void BytecodeRegExpMacroAssembler::CheckAtStart(BlockLabel* on_at_start) { |
272 Emit(BC_CHECK_AT_START, 0); | 244 Emit(BC_CHECK_AT_START, 0); |
273 EmitOrLink(on_at_start); | 245 EmitOrLink(on_at_start); |
274 } | 246 } |
275 | 247 |
276 | |
277 void BytecodeRegExpMacroAssembler::CheckNotAtStart( | 248 void BytecodeRegExpMacroAssembler::CheckNotAtStart( |
278 BlockLabel* on_not_at_start) { | 249 BlockLabel* on_not_at_start) { |
279 Emit(BC_CHECK_NOT_AT_START, 0); | 250 Emit(BC_CHECK_NOT_AT_START, 0); |
280 EmitOrLink(on_not_at_start); | 251 EmitOrLink(on_not_at_start); |
281 } | 252 } |
282 | 253 |
283 | |
284 void BytecodeRegExpMacroAssembler::CheckNotCharacter(uint32_t c, | 254 void BytecodeRegExpMacroAssembler::CheckNotCharacter(uint32_t c, |
285 BlockLabel* on_not_equal) { | 255 BlockLabel* on_not_equal) { |
286 if (c > MAX_FIRST_ARG) { | 256 if (c > MAX_FIRST_ARG) { |
287 Emit(BC_CHECK_NOT_4_CHARS, 0); | 257 Emit(BC_CHECK_NOT_4_CHARS, 0); |
288 Emit32(c); | 258 Emit32(c); |
289 } else { | 259 } else { |
290 Emit(BC_CHECK_NOT_CHAR, c); | 260 Emit(BC_CHECK_NOT_CHAR, c); |
291 } | 261 } |
292 EmitOrLink(on_not_equal); | 262 EmitOrLink(on_not_equal); |
293 } | 263 } |
294 | 264 |
295 | |
296 void BytecodeRegExpMacroAssembler::CheckCharacterAfterAnd( | 265 void BytecodeRegExpMacroAssembler::CheckCharacterAfterAnd( |
297 uint32_t c, | 266 uint32_t c, |
298 uint32_t mask, | 267 uint32_t mask, |
299 BlockLabel* on_equal) { | 268 BlockLabel* on_equal) { |
300 if (c > MAX_FIRST_ARG) { | 269 if (c > MAX_FIRST_ARG) { |
301 Emit(BC_AND_CHECK_4_CHARS, 0); | 270 Emit(BC_AND_CHECK_4_CHARS, 0); |
302 Emit32(c); | 271 Emit32(c); |
303 } else { | 272 } else { |
304 Emit(BC_AND_CHECK_CHAR, c); | 273 Emit(BC_AND_CHECK_CHAR, c); |
305 } | 274 } |
306 Emit32(mask); | 275 Emit32(mask); |
307 EmitOrLink(on_equal); | 276 EmitOrLink(on_equal); |
308 } | 277 } |
309 | 278 |
310 | |
311 void BytecodeRegExpMacroAssembler::CheckNotCharacterAfterAnd( | 279 void BytecodeRegExpMacroAssembler::CheckNotCharacterAfterAnd( |
312 uint32_t c, | 280 uint32_t c, |
313 uint32_t mask, | 281 uint32_t mask, |
314 BlockLabel* on_not_equal) { | 282 BlockLabel* on_not_equal) { |
315 if (c > MAX_FIRST_ARG) { | 283 if (c > MAX_FIRST_ARG) { |
316 Emit(BC_AND_CHECK_NOT_4_CHARS, 0); | 284 Emit(BC_AND_CHECK_NOT_4_CHARS, 0); |
317 Emit32(c); | 285 Emit32(c); |
318 } else { | 286 } else { |
319 Emit(BC_AND_CHECK_NOT_CHAR, c); | 287 Emit(BC_AND_CHECK_NOT_CHAR, c); |
320 } | 288 } |
321 Emit32(mask); | 289 Emit32(mask); |
322 EmitOrLink(on_not_equal); | 290 EmitOrLink(on_not_equal); |
323 } | 291 } |
324 | 292 |
325 | |
326 void BytecodeRegExpMacroAssembler::CheckNotCharacterAfterMinusAnd( | 293 void BytecodeRegExpMacroAssembler::CheckNotCharacterAfterMinusAnd( |
327 uint16_t c, | 294 uint16_t c, |
328 uint16_t minus, | 295 uint16_t minus, |
329 uint16_t mask, | 296 uint16_t mask, |
330 BlockLabel* on_not_equal) { | 297 BlockLabel* on_not_equal) { |
331 Emit(BC_MINUS_AND_CHECK_NOT_CHAR, c); | 298 Emit(BC_MINUS_AND_CHECK_NOT_CHAR, c); |
332 Emit16(minus); | 299 Emit16(minus); |
333 Emit16(mask); | 300 Emit16(mask); |
334 EmitOrLink(on_not_equal); | 301 EmitOrLink(on_not_equal); |
335 } | 302 } |
336 | 303 |
337 | |
338 void BytecodeRegExpMacroAssembler::CheckCharacterInRange( | 304 void BytecodeRegExpMacroAssembler::CheckCharacterInRange( |
339 uint16_t from, | 305 uint16_t from, |
340 uint16_t to, | 306 uint16_t to, |
341 BlockLabel* on_in_range) { | 307 BlockLabel* on_in_range) { |
342 Emit(BC_CHECK_CHAR_IN_RANGE, 0); | 308 Emit(BC_CHECK_CHAR_IN_RANGE, 0); |
343 Emit16(from); | 309 Emit16(from); |
344 Emit16(to); | 310 Emit16(to); |
345 EmitOrLink(on_in_range); | 311 EmitOrLink(on_in_range); |
346 } | 312 } |
347 | 313 |
348 | |
349 void BytecodeRegExpMacroAssembler::CheckCharacterNotInRange( | 314 void BytecodeRegExpMacroAssembler::CheckCharacterNotInRange( |
350 uint16_t from, | 315 uint16_t from, |
351 uint16_t to, | 316 uint16_t to, |
352 BlockLabel* on_not_in_range) { | 317 BlockLabel* on_not_in_range) { |
353 Emit(BC_CHECK_CHAR_NOT_IN_RANGE, 0); | 318 Emit(BC_CHECK_CHAR_NOT_IN_RANGE, 0); |
354 Emit16(from); | 319 Emit16(from); |
355 Emit16(to); | 320 Emit16(to); |
356 EmitOrLink(on_not_in_range); | 321 EmitOrLink(on_not_in_range); |
357 } | 322 } |
358 | 323 |
359 | |
360 void BytecodeRegExpMacroAssembler::CheckBitInTable(const TypedData& table, | 324 void BytecodeRegExpMacroAssembler::CheckBitInTable(const TypedData& table, |
361 BlockLabel* on_bit_set) { | 325 BlockLabel* on_bit_set) { |
362 Emit(BC_CHECK_BIT_IN_TABLE, 0); | 326 Emit(BC_CHECK_BIT_IN_TABLE, 0); |
363 EmitOrLink(on_bit_set); | 327 EmitOrLink(on_bit_set); |
364 for (int i = 0; i < kTableSize; i += kBitsPerByte) { | 328 for (int i = 0; i < kTableSize; i += kBitsPerByte) { |
365 int byte = 0; | 329 int byte = 0; |
366 for (int j = 0; j < kBitsPerByte; j++) { | 330 for (int j = 0; j < kBitsPerByte; j++) { |
367 if (table.GetUint8(i + j) != 0) byte |= 1 << j; | 331 if (table.GetUint8(i + j) != 0) byte |= 1 << j; |
368 } | 332 } |
369 Emit8(byte); | 333 Emit8(byte); |
370 } | 334 } |
371 } | 335 } |
372 | 336 |
373 | |
374 void BytecodeRegExpMacroAssembler::CheckNotBackReference( | 337 void BytecodeRegExpMacroAssembler::CheckNotBackReference( |
375 intptr_t start_reg, | 338 intptr_t start_reg, |
376 BlockLabel* on_not_equal) { | 339 BlockLabel* on_not_equal) { |
377 ASSERT(start_reg >= 0); | 340 ASSERT(start_reg >= 0); |
378 ASSERT(start_reg <= kMaxRegister); | 341 ASSERT(start_reg <= kMaxRegister); |
379 Emit(BC_CHECK_NOT_BACK_REF, start_reg); | 342 Emit(BC_CHECK_NOT_BACK_REF, start_reg); |
380 EmitOrLink(on_not_equal); | 343 EmitOrLink(on_not_equal); |
381 } | 344 } |
382 | 345 |
383 | |
384 void BytecodeRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase( | 346 void BytecodeRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase( |
385 intptr_t start_reg, | 347 intptr_t start_reg, |
386 BlockLabel* on_not_equal) { | 348 BlockLabel* on_not_equal) { |
387 ASSERT(start_reg >= 0); | 349 ASSERT(start_reg >= 0); |
388 ASSERT(start_reg <= kMaxRegister); | 350 ASSERT(start_reg <= kMaxRegister); |
389 Emit(BC_CHECK_NOT_BACK_REF_NO_CASE, start_reg); | 351 Emit(BC_CHECK_NOT_BACK_REF_NO_CASE, start_reg); |
390 EmitOrLink(on_not_equal); | 352 EmitOrLink(on_not_equal); |
391 } | 353 } |
392 | 354 |
393 | |
394 void BytecodeRegExpMacroAssembler::IfRegisterLT(intptr_t register_index, | 355 void BytecodeRegExpMacroAssembler::IfRegisterLT(intptr_t register_index, |
395 intptr_t comparand, | 356 intptr_t comparand, |
396 BlockLabel* on_less_than) { | 357 BlockLabel* on_less_than) { |
397 ASSERT(register_index >= 0); | 358 ASSERT(register_index >= 0); |
398 ASSERT(register_index <= kMaxRegister); | 359 ASSERT(register_index <= kMaxRegister); |
399 Emit(BC_CHECK_REGISTER_LT, register_index); | 360 Emit(BC_CHECK_REGISTER_LT, register_index); |
400 Emit32(comparand); | 361 Emit32(comparand); |
401 EmitOrLink(on_less_than); | 362 EmitOrLink(on_less_than); |
402 } | 363 } |
403 | 364 |
404 | |
405 void BytecodeRegExpMacroAssembler::IfRegisterGE( | 365 void BytecodeRegExpMacroAssembler::IfRegisterGE( |
406 intptr_t register_index, | 366 intptr_t register_index, |
407 intptr_t comparand, | 367 intptr_t comparand, |
408 BlockLabel* on_greater_or_equal) { | 368 BlockLabel* on_greater_or_equal) { |
409 ASSERT(register_index >= 0); | 369 ASSERT(register_index >= 0); |
410 ASSERT(register_index <= kMaxRegister); | 370 ASSERT(register_index <= kMaxRegister); |
411 Emit(BC_CHECK_REGISTER_GE, register_index); | 371 Emit(BC_CHECK_REGISTER_GE, register_index); |
412 Emit32(comparand); | 372 Emit32(comparand); |
413 EmitOrLink(on_greater_or_equal); | 373 EmitOrLink(on_greater_or_equal); |
414 } | 374 } |
415 | 375 |
416 | |
417 void BytecodeRegExpMacroAssembler::IfRegisterEqPos(intptr_t register_index, | 376 void BytecodeRegExpMacroAssembler::IfRegisterEqPos(intptr_t register_index, |
418 BlockLabel* on_eq) { | 377 BlockLabel* on_eq) { |
419 ASSERT(register_index >= 0); | 378 ASSERT(register_index >= 0); |
420 ASSERT(register_index <= kMaxRegister); | 379 ASSERT(register_index <= kMaxRegister); |
421 Emit(BC_CHECK_REGISTER_EQ_POS, register_index); | 380 Emit(BC_CHECK_REGISTER_EQ_POS, register_index); |
422 EmitOrLink(on_eq); | 381 EmitOrLink(on_eq); |
423 } | 382 } |
424 | 383 |
425 | |
426 RawTypedData* BytecodeRegExpMacroAssembler::GetBytecode() { | 384 RawTypedData* BytecodeRegExpMacroAssembler::GetBytecode() { |
427 BindBlock(&backtrack_); | 385 BindBlock(&backtrack_); |
428 Emit(BC_POP_BT, 0); | 386 Emit(BC_POP_BT, 0); |
429 | 387 |
430 intptr_t len = length(); | 388 intptr_t len = length(); |
431 const TypedData& bytecode = | 389 const TypedData& bytecode = |
432 TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, len)); | 390 TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, len)); |
433 | 391 |
434 NoSafepointScope no_safepoint; | 392 NoSafepointScope no_safepoint; |
435 memmove(bytecode.DataAddr(0), buffer_->data(), len); | 393 memmove(bytecode.DataAddr(0), buffer_->data(), len); |
436 | 394 |
437 return bytecode.raw(); | 395 return bytecode.raw(); |
438 } | 396 } |
439 | 397 |
440 | |
441 intptr_t BytecodeRegExpMacroAssembler::length() { | 398 intptr_t BytecodeRegExpMacroAssembler::length() { |
442 return pc_; | 399 return pc_; |
443 } | 400 } |
444 | 401 |
445 | |
446 void BytecodeRegExpMacroAssembler::Expand() { | 402 void BytecodeRegExpMacroAssembler::Expand() { |
447 // BOGUS | 403 // BOGUS |
448 buffer_->Add(0); | 404 buffer_->Add(0); |
449 buffer_->Add(0); | 405 buffer_->Add(0); |
450 buffer_->Add(0); | 406 buffer_->Add(0); |
451 buffer_->Add(0); | 407 buffer_->Add(0); |
452 intptr_t x = buffer_->length(); | 408 intptr_t x = buffer_->length(); |
453 for (intptr_t i = 0; i < x; i++) | 409 for (intptr_t i = 0; i < x; i++) |
454 buffer_->Add(0); | 410 buffer_->Add(0); |
455 } | 411 } |
456 | 412 |
457 | |
458 static intptr_t Prepare(const RegExp& regexp, | 413 static intptr_t Prepare(const RegExp& regexp, |
459 const String& subject, | 414 const String& subject, |
460 bool sticky, | 415 bool sticky, |
461 Zone* zone) { | 416 Zone* zone) { |
462 bool is_one_byte = | 417 bool is_one_byte = |
463 subject.IsOneByteString() || subject.IsExternalOneByteString(); | 418 subject.IsOneByteString() || subject.IsExternalOneByteString(); |
464 | 419 |
465 if (regexp.bytecode(is_one_byte, sticky) == TypedData::null()) { | 420 if (regexp.bytecode(is_one_byte, sticky) == TypedData::null()) { |
466 const String& pattern = String::Handle(zone, regexp.pattern()); | 421 const String& pattern = String::Handle(zone, regexp.pattern()); |
467 #if !defined(PRODUCT) | 422 #if !defined(PRODUCT) |
(...skipping 27 matching lines...) Expand all Loading... |
495 regexp.set_num_registers(result.num_registers); | 450 regexp.set_num_registers(result.num_registers); |
496 regexp.set_bytecode(is_one_byte, sticky, *(result.bytecode)); | 451 regexp.set_bytecode(is_one_byte, sticky, *(result.bytecode)); |
497 } | 452 } |
498 | 453 |
499 ASSERT(regexp.num_registers() != -1); | 454 ASSERT(regexp.num_registers() != -1); |
500 | 455 |
501 return regexp.num_registers() + | 456 return regexp.num_registers() + |
502 (Smi::Value(regexp.num_bracket_expressions()) + 1) * 2; | 457 (Smi::Value(regexp.num_bracket_expressions()) + 1) * 2; |
503 } | 458 } |
504 | 459 |
505 | |
506 static IrregexpInterpreter::IrregexpResult ExecRaw(const RegExp& regexp, | 460 static IrregexpInterpreter::IrregexpResult ExecRaw(const RegExp& regexp, |
507 const String& subject, | 461 const String& subject, |
508 intptr_t index, | 462 intptr_t index, |
509 bool sticky, | 463 bool sticky, |
510 int32_t* output, | 464 int32_t* output, |
511 intptr_t output_size, | 465 intptr_t output_size, |
512 Zone* zone) { | 466 Zone* zone) { |
513 bool is_one_byte = | 467 bool is_one_byte = |
514 subject.IsOneByteString() || subject.IsExternalOneByteString(); | 468 subject.IsOneByteString() || subject.IsExternalOneByteString(); |
515 | 469 |
(...skipping 26 matching lines...) Expand all Loading... |
542 Thread* thread = Thread::Current(); | 496 Thread* thread = Thread::Current(); |
543 Isolate* isolate = thread->isolate(); | 497 Isolate* isolate = thread->isolate(); |
544 const Instance& exception = | 498 const Instance& exception = |
545 Instance::Handle(isolate->object_store()->stack_overflow()); | 499 Instance::Handle(isolate->object_store()->stack_overflow()); |
546 Exceptions::Throw(thread, exception); | 500 Exceptions::Throw(thread, exception); |
547 UNREACHABLE(); | 501 UNREACHABLE(); |
548 } | 502 } |
549 return result; | 503 return result; |
550 } | 504 } |
551 | 505 |
552 | |
553 RawInstance* BytecodeRegExpMacroAssembler::Interpret(const RegExp& regexp, | 506 RawInstance* BytecodeRegExpMacroAssembler::Interpret(const RegExp& regexp, |
554 const String& subject, | 507 const String& subject, |
555 const Smi& start_index, | 508 const Smi& start_index, |
556 bool sticky, | 509 bool sticky, |
557 Zone* zone) { | 510 Zone* zone) { |
558 intptr_t required_registers = Prepare(regexp, subject, sticky, zone); | 511 intptr_t required_registers = Prepare(regexp, subject, sticky, zone); |
559 if (required_registers < 0) { | 512 if (required_registers < 0) { |
560 // Compiling failed with an exception. | 513 // Compiling failed with an exception. |
561 UNREACHABLE(); | 514 UNREACHABLE(); |
562 } | 515 } |
(...skipping 29 matching lines...) Expand all Loading... |
592 | 545 |
593 return result.raw(); | 546 return result.raw(); |
594 } | 547 } |
595 if (result == IrregexpInterpreter::RE_EXCEPTION) { | 548 if (result == IrregexpInterpreter::RE_EXCEPTION) { |
596 UNREACHABLE(); | 549 UNREACHABLE(); |
597 } | 550 } |
598 ASSERT(result == IrregexpInterpreter::RE_FAILURE); | 551 ASSERT(result == IrregexpInterpreter::RE_FAILURE); |
599 return Instance::null(); | 552 return Instance::null(); |
600 } | 553 } |
601 | 554 |
602 | |
603 } // namespace dart | 555 } // namespace dart |
OLD | NEW |