Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(976)

Side by Side Diff: runtime/vm/regexp_assembler.h

Issue 539153002: Port and integrate the irregexp engine from V8 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Port remaining V8 regexp tests and fix exposed bugs. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
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.
4
5 #ifndef VM_REGEXP_ASSEMBLER_H_
6 #define VM_REGEXP_ASSEMBLER_H_
7
8 #include "vm/assembler.h"
9 #include "vm/intermediate_language.h"
10 #include "vm/object.h"
11
12 namespace dart {
13
14 /// Convenience wrapper around a BlockEntryInstr pointer.
15 class BlockLabel : public ValueObject {
16 public:
17 BlockLabel()
18 : block_(new JoinEntryInstr(-1, -1)),
19 is_bound_(false),
20 is_linked_(false) { }
21
22 BlockLabel(const BlockLabel& that)
Florian Schneider 2014/10/01 17:04:13 Is the copy constructor and operator= needed? If y
jgruber1 2014/10/03 18:59:51 Done.
23 : ValueObject(),
24 block_(that.block_),
25 is_bound_(that.is_bound_),
26 is_linked_(that.is_linked_) { }
27
28 BlockLabel& operator=(const BlockLabel& that) {
29 block_ = that.block_;
30 is_bound_ = that.is_bound_;
31 is_linked_ = that.is_linked_;
32 return *this;
33 }
34
35 JoinEntryInstr* block() const { return block_; }
36
37 bool IsBound() const { return is_bound_; }
38 void SetBound(intptr_t block_id) {
39 ASSERT(!is_bound_);
40 block_->set_block_id(block_id);
41 is_bound_ = true;
42 }
43
44 bool IsLinked() const { return !is_bound_ && is_linked_; }
45 void SetLinked() {
46 is_linked_ = true;
47 }
48
49 intptr_t Position() const {
50 ASSERT(IsBound());
51 return block_->block_id();
52 }
53
54 private:
55 JoinEntryInstr* block_;
56
57 bool is_bound_;
58 bool is_linked_;
59 };
60
61
62 class RegExpMacroAssembler : public ZoneAllocated {
63 public:
64 // The implementation must be able to handle at least:
65 static const intptr_t kMaxRegister = (1 << 16) - 1;
66 static const intptr_t kMaxCPOffset = (1 << 15) - 1;
67 static const intptr_t kMinCPOffset = -(1 << 15);
68
69 static const intptr_t kTableSizeBits = 7;
70 static const intptr_t kTableSize = 1 << kTableSizeBits;
71 static const intptr_t kTableMask = kTableSize - 1;
72
73 enum {
74 kParamStringIndex = 0,
75 kParamStartOffsetIndex,
76 kParamCount = 2
Florian Schneider 2014/10/02 11:58:12 Remove =2 here.
jgruber1 2014/10/03 18:59:51 Done.
77 };
78
79 enum IrregexpImplementation {
80 kIRImplementation
81 };
82
83 enum StackCheckFlag {
84 kNoStackLimitCheck = false,
Florian Schneider 2014/10/02 11:58:12 Make this 0. Or make two static const bool variab
jgruber1 2014/10/03 18:59:51 Removed the entire enum.
85 kCheckStackLimit = true
86 };
87
88 explicit RegExpMacroAssembler(Isolate* isolate);
89 virtual ~RegExpMacroAssembler();
90 // The maximal number of pushes between stack checks. Users must supply
91 // kCheckStackLimit flag to push operations (instead of kNoStackLimitCheck)
92 // at least once for every stack_limit() pushes that are executed.
93 virtual intptr_t stack_limit_slack() = 0;
94 virtual bool CanReadUnaligned() = 0;
95 virtual void AdvanceCurrentPosition(intptr_t by) = 0; // Signed cp change.
96 virtual void AdvanceRegister(intptr_t reg, intptr_t by) = 0; // r[reg] += by.
97 // Continues execution from the position pushed on the top of the backtrack
98 // stack by an earlier PushBacktrack(BlockLabel*).
99 virtual void Backtrack() = 0;
100 virtual void BindBlock(BlockLabel* label) = 0;
101 virtual void CheckAtStart(BlockLabel* on_at_start) = 0;
102 // Dispatch after looking the current character up in a 2-bits-per-entry
103 // map. The destinations vector has up to 4 labels.
104 virtual void CheckCharacter(unsigned c, BlockLabel* on_equal) = 0;
105 // Bitwise and the current character with the given constant and then
106 // check for a match with c.
107 virtual void CheckCharacterAfterAnd(unsigned c,
108 unsigned and_with,
109 BlockLabel* on_equal) = 0;
110 virtual void CheckCharacterGT(uint16_t limit, BlockLabel* on_greater) = 0;
111 virtual void CheckCharacterLT(uint16_t limit, BlockLabel* on_less) = 0;
112 virtual void CheckGreedyLoop(BlockLabel* on_tos_equals_current_position) = 0;
113 virtual void CheckNotAtStart(BlockLabel* on_not_at_start) = 0;
114 virtual void CheckNotBackReference(
115 intptr_t start_reg, BlockLabel* on_no_match) = 0;
116 virtual void CheckNotBackReferenceIgnoreCase(intptr_t start_reg,
117 BlockLabel* on_no_match) = 0;
118 // Check the current character for a match with a literal character. If we
119 // fail to match then goto the on_failure label. End of input always
120 // matches. If the label is NULL then we should pop a backtrack address off
121 // the stack and go to that.
122 virtual void CheckNotCharacter(unsigned c, BlockLabel* on_not_equal) = 0;
123 virtual void CheckNotCharacterAfterAnd(unsigned c,
124 unsigned and_with,
125 BlockLabel* on_not_equal) = 0;
126 // Subtract a constant from the current character, then and with the given
127 // constant and then check for a match with c.
128 virtual void CheckNotCharacterAfterMinusAnd(uint16_t c,
129 uint16_t minus,
130 uint16_t and_with,
131 BlockLabel* on_not_equal) = 0;
132 virtual void CheckCharacterInRange(uint16_t from,
133 uint16_t to, // Both inclusive.
134 BlockLabel* on_in_range) = 0;
135 virtual void CheckCharacterNotInRange(uint16_t from,
136 uint16_t to, // Both inclusive.
137 BlockLabel* on_not_in_range) = 0;
138
139 // The current character (modulus the kTableSize) is looked up in the byte
140 // array, and if the found byte is non-zero, we jump to the on_bit_set label.
141 virtual void CheckBitInTable(const TypedData& table,
142 BlockLabel* on_bit_set) = 0;
143
144 // Checks whether the given offset from the current position is before
145 // the end of the string. May overwrite the current character.
146 virtual void CheckPosition(intptr_t cp_offset, BlockLabel* on_outside_input) {
147 LoadCurrentCharacter(cp_offset, on_outside_input, true);
148 }
149 // Check whether a standard/default character class matches the current
150 // character. Returns false if the type of special character class does
151 // not have custom support.
152 // May clobber the current loaded character.
153 virtual bool CheckSpecialCharacterClass(uint16_t type,
154 BlockLabel* on_no_match) {
155 return false;
156 }
157 virtual void Fail() = 0;
158 // Check whether a register is >= a given constant and go to a label if it
159 // is. Backtracks instead if the label is NULL.
160 virtual void IfRegisterGE(
161 intptr_t reg, intptr_t comparand, BlockLabel* if_ge) = 0;
162 // Check whether a register is < a given constant and go to a label if it is.
163 // Backtracks instead if the label is NULL.
164 virtual void IfRegisterLT(
165 intptr_t reg, intptr_t comparand, BlockLabel* if_lt) = 0;
166 // Check whether a register is == to the current position and go to a
167 // label if it is.
168 virtual void IfRegisterEqPos(intptr_t reg, BlockLabel* if_eq) = 0;
169 virtual IrregexpImplementation Implementation() = 0;
170 // The assembler is closed, iff there is no current instruction assigned.
171 virtual bool IsClosed() const = 0;
172 // Jump to the target label without setting it as the current instruction.
173 virtual void GoTo(BlockLabel* to) = 0;
174 virtual void LoadCurrentCharacter(intptr_t cp_offset,
175 BlockLabel* on_end_of_input,
176 bool check_bounds = true,
177 intptr_t characters = 1) = 0;
178 virtual void PopCurrentPosition() = 0;
179 virtual void PopRegister(intptr_t register_index) = 0;
180 // Prints string within the generated code. Used for debugging.
181 virtual void Print(const char* str) = 0;
182 // Prints all emitted blocks.
183 virtual void PrintBlocks() = 0;
184 // Pushes the label on the backtrack stack, so that a following Backtrack
185 // will go to this label. Always checks the backtrack stack limit.
186 virtual void PushBacktrack(BlockLabel* label) = 0;
187 virtual void PushCurrentPosition() = 0;
188 virtual void PushRegister(intptr_t register_index,
189 StackCheckFlag check_stack_limit) = 0;
190 virtual void ReadCurrentPositionFromRegister(intptr_t reg) = 0;
191 virtual void ReadStackPointerFromRegister(intptr_t reg) = 0;
192 virtual void SetCurrentPositionFromEnd(intptr_t by) = 0;
193 virtual void SetRegister(intptr_t register_index, intptr_t to) = 0;
194 // Return whether the matching (with a global regexp) will be restarted.
195 virtual bool Succeed() = 0;
196 virtual void WriteCurrentPositionToRegister(
197 intptr_t reg, intptr_t cp_offset) = 0;
198 virtual void ClearRegisters(intptr_t reg_from, intptr_t reg_to) = 0;
199 virtual void WriteStackPointerToRegister(intptr_t reg) = 0;
200
201 // Controls the generation of large inlined constants in the code.
202 void set_slow_safe(bool ssc) { slow_safe_compiler_ = ssc; }
203 bool slow_safe() { return slow_safe_compiler_; }
204
205 enum GlobalMode { NOT_GLOBAL, GLOBAL, GLOBAL_NO_ZERO_LENGTH_CHECK };
206 // Set whether the regular expression has the global flag. Exiting due to
207 // a failure in a global regexp may still mean success overall.
208 inline void set_global_mode(GlobalMode mode) { global_mode_ = mode; }
209 inline bool global() { return global_mode_ != NOT_GLOBAL; }
210 inline bool global_with_zero_length_check() {
211 return global_mode_ == GLOBAL;
212 }
213
214 Isolate* isolate() const { return isolate_; }
215
216 private:
217 bool slow_safe_compiler_;
218 bool global_mode_;
219 Isolate* isolate_;
220 };
221
222
223 class IRRegExpMacroAssembler: public RegExpMacroAssembler {
224 public:
225 // Type of input string to generate code for.
226 enum Mode { ASCII = 1, UC16 = 2 };
227
228 // Result of calling generated native RegExp code.
229 // RETRY: Something significant changed during execution, and the matching
230 // should be retried from scratch.
231 // EXCEPTION: Something failed during execution. If no exception has been
232 // thrown, it's an internal out-of-memory, and the caller should
233 // throw the exception.
234 // FAILURE: Matching failed.
235 // SUCCESS: Matching succeeded, and the output array has been filled with
236 // capture positions.
237 enum Result { RETRY = -2, EXCEPTION = -1, FAILURE = 0, SUCCESS = 1 };
238
239 IRRegExpMacroAssembler(intptr_t specialization_cid,
240 intptr_t capture_count,
241 const ParsedFunction* parsed_function,
242 ZoneGrowableArray<const ICData*>* ic_data_array,
243 Isolate* isolate);
244 virtual ~IRRegExpMacroAssembler();
245
246 virtual bool CanReadUnaligned();
247
248 // Compares two-byte strings case insensitively.
249 // Called from generated RegExp code.
250 static RawBool* CaseInsensitiveCompareUC16(
251 RawString* str_raw,
252 RawSmi* lhs_index_raw,
253 RawSmi* rhs_index_raw,
254 RawSmi* length_raw);
255
256 static RawArray* Execute(const Function& function,
257 const String& input,
258 const Smi& start_offset,
259 Isolate* isolate);
260
261 virtual bool IsClosed() const { return (current_instruction_ == NULL); }
262
263 virtual intptr_t stack_limit_slack();
264 virtual void AdvanceCurrentPosition(intptr_t by);
265 virtual void AdvanceRegister(intptr_t reg, intptr_t by);
266 virtual void Backtrack();
267 virtual void BindBlock(BlockLabel* label);
268 virtual void CheckAtStart(BlockLabel* on_at_start);
269 virtual void CheckCharacter(uint32_t c, BlockLabel* on_equal);
270 virtual void CheckCharacterAfterAnd(uint32_t c,
271 uint32_t mask,
272 BlockLabel* on_equal);
273 virtual void CheckCharacterGT(uint16_t limit, BlockLabel* on_greater);
274 virtual void CheckCharacterLT(uint16_t limit, BlockLabel* on_less);
275 // A "greedy loop" is a loop that is both greedy and with a simple
276 // body. It has a particularly simple implementation.
277 virtual void CheckGreedyLoop(BlockLabel* on_tos_equals_current_position);
278 virtual void CheckNotAtStart(BlockLabel* on_not_at_start);
279 virtual void CheckNotBackReference(intptr_t start_reg,
280 BlockLabel* on_no_match);
281 virtual void CheckNotBackReferenceIgnoreCase(intptr_t start_reg,
282 BlockLabel* on_no_match);
283 virtual void CheckNotCharacter(uint32_t c, BlockLabel* on_not_equal);
284 virtual void CheckNotCharacterAfterAnd(uint32_t c,
285 uint32_t mask,
286 BlockLabel* on_not_equal);
287 virtual void CheckNotCharacterAfterMinusAnd(uint16_t c,
288 uint16_t minus,
289 uint16_t mask,
290 BlockLabel* on_not_equal);
291 virtual void CheckCharacterInRange(uint16_t from,
292 uint16_t to,
293 BlockLabel* on_in_range);
294 virtual void CheckCharacterNotInRange(uint16_t from,
295 uint16_t to,
296 BlockLabel* on_not_in_range);
297 virtual void CheckBitInTable(const TypedData& table, BlockLabel* on_bit_set);
298
299 // Checks whether the given offset from the current position is before
300 // the end of the string.
301 virtual void CheckPosition(intptr_t cp_offset, BlockLabel* on_outside_input);
302 virtual bool CheckSpecialCharacterClass(
303 uint16_t type, BlockLabel* on_no_match);
304 virtual void Fail();
305 virtual void IfRegisterGE(intptr_t reg,
306 intptr_t comparand, BlockLabel* if_ge);
307 virtual void IfRegisterLT(intptr_t reg,
308 intptr_t comparand, BlockLabel* if_lt);
309 virtual void IfRegisterEqPos(intptr_t reg, BlockLabel* if_eq);
310 virtual IrregexpImplementation Implementation();
311 virtual void GoTo(BlockLabel* to);
312 virtual void LoadCurrentCharacter(intptr_t cp_offset,
313 BlockLabel* on_end_of_input,
314 bool check_bounds = true,
315 intptr_t characters = 1);
316 virtual void PopCurrentPosition();
317 virtual void PopRegister(intptr_t register_index);
318 virtual void Print(const char* str);
319 virtual void PushBacktrack(BlockLabel* label);
320 virtual void PushCurrentPosition();
321 virtual void PushRegister(intptr_t register_index,
322 StackCheckFlag check_stack_limit);
323 virtual void ReadCurrentPositionFromRegister(intptr_t reg);
324 virtual void ReadStackPointerFromRegister(intptr_t reg);
325 virtual void SetCurrentPositionFromEnd(intptr_t by);
326 virtual void SetRegister(intptr_t register_index, intptr_t to);
327 virtual bool Succeed();
328 virtual void WriteCurrentPositionToRegister(intptr_t reg, intptr_t cp_offset);
329 virtual void ClearRegisters(intptr_t reg_from, intptr_t reg_to);
330 virtual void WriteStackPointerToRegister(intptr_t reg);
331
332 virtual void PrintBlocks();
333
334 GraphEntryInstr* graph_entry() const { return entry_block_; }
335
336 intptr_t num_stack_locals() const { return local_id.Count(); }
337 intptr_t num_blocks() const { return block_id.Count(); }
338
339 // A table mapping block ids to block offsets, used to look up offsets
340 // for indirect goto instructions.
341 void FinalizeBlockOffsetTable();
342
343 // Fill in indirect goto successors.
344 void FinalizeIndirectGotos();
345
346 private:
347 // Generate the contents of preset blocks. The entry block is the entry point
348 // of the generated code.
349 void GenerateEntryBlock();
350 // Performs backtracking, i.e. popping an offset from the stack and doing
351 // an indirect goto.
352 void GenerateBacktrackBlock();
353 // Copies capture indices into the result area and returns true.
354 void GenerateSuccessBlock();
355 // Returns false.
356 void GenerateExitBlock();
357
358 enum ComparisonKind {
359 kEQ,
360 kNE,
361 kLT,
362 kGT,
363 kLTE,
364 kGTE,
365 };
366
367 struct InstanceCallDescriptor : public ValueObject {
Florian Schneider 2014/10/01 17:04:13 Maybe not inherit from ValueObject
jgruber1 2014/10/03 18:59:51 Done.
368 // Standard (i.e. most non-Smi) functions.
369 explicit InstanceCallDescriptor(const String& name)
370 : name(&name),
371 token_kind(Token::kILLEGAL),
372 checked_argument_count(1) { }
373
374 // Special cases for Smi and indexing functions.
375 explicit InstanceCallDescriptor(Token::Kind token_kind)
376 : token_kind(token_kind) {
377 switch (token_kind) {
378 case Token::kEQ:
379 name = &Symbols::EqualOperator();
380 checked_argument_count = 2;
381 break;
382 case Token::kADD:
383 name = &Symbols::Plus();
384 checked_argument_count = 2;
385 break;
386 case Token::kSUB:
387 name = &Symbols::Minus();
388 checked_argument_count = 2;
389 break;
390 case Token::kBIT_OR:
391 name = &Symbols::BitOr();
392 checked_argument_count = 2;
393 break;
394 case Token::kBIT_AND:
395 name = &Symbols::BitAnd();
396 checked_argument_count = 2;
397 break;
398 case Token::kLT:
399 name = &Symbols::LAngleBracket();
400 checked_argument_count = 2;
401 break;
402 case Token::kLTE:
403 name = &Symbols::LessEqualOperator();
404 checked_argument_count = 2;
405 break;
406 case Token::kGT:
407 name = &Symbols::RAngleBracket();
408 checked_argument_count = 2;
409 break;
410 case Token::kGTE:
411 name = &Symbols::GreaterEqualOperator();
412 checked_argument_count = 2;
413 break;
414 case Token::kNEGATE:
415 name = &Symbols::UnaryMinus();
416 checked_argument_count = 1;
417 break;
418 case Token::kINDEX:
419 name = &Symbols::IndexToken();
420 checked_argument_count = 2;
421 break;
422 case Token::kASSIGN_INDEX:
423 name = &Symbols::AssignIndexToken();
424 checked_argument_count = 3;
425 break;
426 default:
427 UNREACHABLE();
428 }
429 }
430
431 InstanceCallDescriptor(const InstanceCallDescriptor& that)
Florian Schneider 2014/10/01 17:04:13 Needed?
jgruber1 2014/10/03 18:59:51 Done.
432 : ValueObject(),
433 name(that.name),
434 token_kind(that.token_kind),
435 checked_argument_count(that.checked_argument_count) { }
436
437 const String* name;
438 Token::Kind token_kind;
439 intptr_t checked_argument_count;
440 };
441
442 LocalVariable* Local(const String& name);
443 LocalVariable* Parameter(const String& name, intptr_t index) const;
444
445 ConstantInstr* Int64Constant(int64_t value) const;
446 ConstantInstr* Uint64Constant(uint64_t value) const;
447 ConstantInstr* BoolConstant(bool value) const;
448 ConstantInstr* StringConstant(const char* value) const;
449
450 // The word character map static member of the RegExp class.
451 // Byte map of one byte characters with a 0xff if the character is a word
452 // character (digit, letter or underscore) and 0x00 otherwise.
453 // Used by generated RegExp code.
454 ConstantInstr* WordCharacterMapConstant() const;
455
456 ComparisonInstr* Comparison(ComparisonKind kind,
457 Definition* lhs, Definition* rhs);
458
459 InstanceCallInstr* InstanceCall(const InstanceCallDescriptor& desc,
460 PushArgumentInstr* arg1) const;
461 InstanceCallInstr* InstanceCall(const InstanceCallDescriptor& desc,
462 PushArgumentInstr* arg1,
463 PushArgumentInstr* arg2) const;
464 InstanceCallInstr* InstanceCall(const InstanceCallDescriptor& desc,
465 PushArgumentInstr* arg1,
466 PushArgumentInstr* arg2,
467 PushArgumentInstr* arg3) const;
468 InstanceCallInstr* InstanceCall(
469 const InstanceCallDescriptor& desc,
470 ZoneGrowableArray<PushArgumentInstr*>* arguments) const;
471
472 StaticCallInstr* StaticCall(const Function& function) const;
473 StaticCallInstr* StaticCall(const Function& function,
474 PushArgumentInstr* arg1) const;
475 StaticCallInstr* StaticCall(const Function& function,
476 PushArgumentInstr* arg1,
477 PushArgumentInstr* arg2) const;
478 StaticCallInstr* StaticCall(
479 const Function& function,
480 ZoneGrowableArray<PushArgumentInstr*>* arguments) const;
481
482 // Creates a new block consisting simply of a goto to dst.
483 TargetEntryInstr* TargetWithJoinGoto(JoinEntryInstr* dst);
484 IndirectEntryInstr* IndirectWithJoinGoto(JoinEntryInstr* dst);
485
486 // Adds, respectively subtracts lhs and rhs and returns the result.
487 Value* Add(PushArgumentInstr* lhs, PushArgumentInstr* rhs);
488 Value* Sub(PushArgumentInstr* lhs, PushArgumentInstr* rhs);
489
490 LoadLocalInstr* LoadLocal(LocalVariable* local) const;
491 void StoreLocal(LocalVariable* local, Value* value);
492
493 PushArgumentInstr* PushArgument(Value* value);
494 PushArgumentInstr* PushLocal(LocalVariable* local);
495
496 // Returns the character within the passed string at the specified index.
497 Value* CharacterAt(Definition* index);
498
499 // Load a number of characters at the given offset from the
500 // current position, into the current-character register.
501 void LoadCurrentCharacterUnchecked(intptr_t cp_offset,
502 intptr_t character_count);
503
504 // Check whether preemption has been requested.
505 void CheckPreemption();
506
507 // Byte size of chars in the string to match (decided by the Mode argument)
508 inline intptr_t char_size() { return static_cast<int>(mode_); }
509
510 // Equivalent to a conditional branch to the label, unless the label
511 // is NULL, in which case it is a conditional Backtrack.
512 void BranchOrBacktrack(ComparisonInstr* comparison,
513 BlockLabel* true_successor);
514
515 // Set up all local variables and parameters.
516 void InitializeLocals();
517
518 // Allocates a new local, and returns the appropriate id for placing it
519 // on the stack.
520 intptr_t GetNextLocalIndex();
521
522 // We never have any copied parameters.
523 intptr_t num_copied_params() const {
524 return 0;
525 }
526
527 // Return the position register at the specified index, creating it if
528 // necessary. Note that the number of such registers can exceed the amount
529 // required by the number of output captures.
530 LocalVariable* position_register(intptr_t index);
531
532 void set_current_instruction(Instruction* instruction);
533
534 // The following functions are responsible for appending instructions
535 // to the current instruction in various ways. The most simple one
536 // is AppendInstruction, which simply appends an instruction and performs
537 // bookkeeping.
538 void AppendInstruction(Instruction* instruction);
539 // Similar to AppendInstruction, but closes the current block by
540 // setting current_instruction_ to NULL.
541 void CloseBlockWith(Instruction* instruction);
542 // Appends definition and allocates a temp index for the result.
543 Value* Bind(Definition* definition);
544 // Appends the definition.
545 void Do(Definition* definition);
546 // Closes the current block with a jump to the specified block.
547 void GoTo(JoinEntryInstr* to);
548
549 // Accessors for our local stack_.
550 void PushStack(Definition* definition);
551 Value* PopStack();
552
553 // Prints the specified argument. Used for debugging.
554 void Print(PushArgumentInstr* argument);
555
556 // A utility class tracking ids of various objects such as blocks, temps, etc.
557 class IdAllocator : public ValueObject {
558 public:
559 IdAllocator() : next_id(0) { }
560
561 intptr_t Count() const { return next_id; }
562 intptr_t Alloc(intptr_t count = 1) {
563 ASSERT(count >= 0);
564 intptr_t current_id = next_id;
565 next_id += count;
566 return current_id;
567 }
568 void Dealloc(intptr_t count = 1) {
569 ASSERT(count <= next_id);
570 next_id -= count;
571 }
572
573 private:
574 intptr_t next_id;
575 };
576
577 // Which mode to generate code for (ASCII or UC16).
578 Mode mode_;
579
580 // Which specific string class to generate code for.
581 intptr_t specialization_cid_;
582
583 // Block entries used internally.
584 GraphEntryInstr* entry_block_;
585 JoinEntryInstr* start_block_;
586 JoinEntryInstr* success_block_;
587 JoinEntryInstr* backtrack_block_;
588 JoinEntryInstr* exit_block_;
589
590 const ParsedFunction* parsed_function_;
591 ZoneGrowableArray<const ICData*>* ic_data_array_;
592
593 // All created blocks are contained within this set. Used for printing
594 // the generated code.
595 GrowableArray<BlockEntryInstr*> blocks_;
596
597 // The current instruction to link to when new code is emitted.
598 Instruction* current_instruction_;
599
600 // A list, acting as the runtime stack for both backtrack locations and
601 // stored positions within the string.
602 LocalVariable* stack_;
603
604 // Stores the current character within the string.
605 LocalVariable* current_character_;
606
607 // Stores the current location within the string as a negative offset
608 // from the end of the string.
609 LocalVariable* current_position_;
610
611 // The string being processed, passed as a function parameter.
612 LocalVariable* string_param_;
613
614 // Stores the length of string_param_.
615 LocalVariable* string_param_length_;
616
617 // The start index within the string, passed as a function parameter.
618 LocalVariable* start_index_param_;
619
620 // An assortment of utility variables.
621 LocalVariable* capture_length_;
622 LocalVariable* match_start_index_;
623 LocalVariable* capture_start_index_;
624 LocalVariable* match_end_index_;
625 LocalVariable* char_in_capture_;
626 LocalVariable* char_in_match_;
627
628 LocalVariable* result_;
629
630 // Stored positions containing group bounds. Generated as needed.
631 const intptr_t position_registers_count_;
632 GrowableArray<LocalVariable*> position_registers_;
633
634 // The actual array object used as the stack.
635 GrowableObjectArray& stack_array_;
636
637 GrowableArray<IndirectGotoInstr*> igotos_;
638
639 IdAllocator block_id;
640 IdAllocator temp_id;
641 IdAllocator arg_id;
642 IdAllocator local_id;
643 IdAllocator indirect_id;
644 };
645
646 } // namespace dart
647
648 #endif // VM_REGEXP_ASSEMBLER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698