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

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: Updated to current version Created 6 years, 3 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)
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 {
srdjan 2014/09/22 22:34:07 Is this object allocated in the C-heap?
jgruber1 2014/09/23 10:58:47 Changed inheritance hierarchy to: 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
77 };
78
79 enum IrregexpImplementation {
80 kIRImplementation
81 };
82
83 enum StackCheckFlag {
84 kNoStackLimitCheck = false,
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 // Jump to the target label, and continue emission there.
159 virtual void GoTo(BlockLabel* to) = 0;
160 // Check whether a register is >= a given constant and go to a label if it
161 // is. Backtracks instead if the label is NULL.
162 virtual void IfRegisterGE(
163 intptr_t reg, intptr_t comparand, BlockLabel* if_ge) = 0;
164 // Check whether a register is < a given constant and go to a label if it is.
165 // Backtracks instead if the label is NULL.
166 virtual void IfRegisterLT(
167 intptr_t reg, intptr_t comparand, BlockLabel* if_lt) = 0;
168 // Check whether a register is == to the current position and go to a
169 // label if it is.
170 virtual void IfRegisterEqPos(intptr_t reg, BlockLabel* if_eq) = 0;
171 virtual IrregexpImplementation Implementation() = 0;
172 // The assembler is closed, iff there is no current instruction assigned.
173 virtual bool IsClosed() const = 0;
174 // Jump to the target label without setting it as the current instruction.
175 virtual void Jump(BlockLabel* to) = 0;
176 virtual void LoadCurrentCharacter(intptr_t cp_offset,
177 BlockLabel* on_end_of_input,
178 bool check_bounds = true,
179 intptr_t characters = 1) = 0;
180 virtual void PopCurrentPosition() = 0;
181 virtual void PopRegister(intptr_t register_index) = 0;
182 // Prints string within the generated code. Used for debugging.
183 virtual void Print(const char* str) = 0;
184 // Prints all emitted blocks.
185 virtual void PrintBlocks() = 0;
186 // Pushes the label on the backtrack stack, so that a following Backtrack
187 // will go to this label. Always checks the backtrack stack limit.
188 virtual void PushBacktrack(BlockLabel* label) = 0;
189 virtual void PushCurrentPosition() = 0;
190 virtual void PushRegister(intptr_t register_index,
191 StackCheckFlag check_stack_limit) = 0;
192 virtual void ReadCurrentPositionFromRegister(intptr_t reg) = 0;
193 virtual void ReadStackPointerFromRegister(intptr_t reg) = 0;
194 virtual void SetCurrentPositionFromEnd(intptr_t by) = 0;
195 virtual void SetRegister(intptr_t register_index, intptr_t to) = 0;
196 // Return whether the matching (with a global regexp) will be restarted.
197 virtual bool Succeed() = 0;
198 virtual void WriteCurrentPositionToRegister(
199 intptr_t reg, intptr_t cp_offset) = 0;
200 virtual void ClearRegisters(intptr_t reg_from, intptr_t reg_to) = 0;
201 virtual void WriteStackPointerToRegister(intptr_t reg) = 0;
202
203 // Controls the generation of large inlined constants in the code.
204 void set_slow_safe(bool ssc) { slow_safe_compiler_ = ssc; }
205 bool slow_safe() { return slow_safe_compiler_; }
206
207 enum GlobalMode { NOT_GLOBAL, GLOBAL, GLOBAL_NO_ZERO_LENGTH_CHECK };
208 // Set whether the regular expression has the global flag. Exiting due to
209 // a failure in a global regexp may still mean success overall.
210 inline void set_global_mode(GlobalMode mode) { global_mode_ = mode; }
211 inline bool global() { return global_mode_ != NOT_GLOBAL; }
212 inline bool global_with_zero_length_check() {
213 return global_mode_ == GLOBAL;
214 }
215
216 Isolate* isolate() const { return isolate_; }
217
218 private:
219 bool slow_safe_compiler_;
220 bool global_mode_;
221 Isolate* isolate_;
222 };
223
224
225 class IRRegExpMacroAssembler: public RegExpMacroAssembler,
226 public ZoneAllocated {
227 public:
228 // Type of input string to generate code for.
229 enum Mode { ASCII = 1, UC16 = 2 };
230
231 // Result of calling generated native RegExp code.
232 // RETRY: Something significant changed during execution, and the matching
233 // should be retried from scratch.
234 // EXCEPTION: Something failed during execution. If no exception has been
235 // thrown, it's an internal out-of-memory, and the caller should
236 // throw the exception.
237 // FAILURE: Matching failed.
238 // SUCCESS: Matching succeeded, and the output array has been filled with
239 // capture positions.
240 enum Result { RETRY = -2, EXCEPTION = -1, FAILURE = 0, SUCCESS = 1 };
241
242 IRRegExpMacroAssembler(intptr_t specialization_cid,
243 intptr_t capture_count,
244 const ParsedFunction* parsed_function,
245 ZoneGrowableArray<const ICData*>* ic_data_array,
246 Isolate* isolate);
247 virtual ~IRRegExpMacroAssembler();
248
249 virtual bool CanReadUnaligned();
250
251 // Compares two-byte strings case insensitively.
252 // Called from generated RegExp code.
253 static RawBool* CaseInsensitiveCompareUC16(
254 RawString* str_raw,
255 RawSmi* lhs_index_raw,
256 RawSmi* rhs_index_raw,
257 RawSmi* length_raw);
258
259 static RawArray* Execute(const Function& function,
260 const String& input,
261 const Smi& start_offset,
262 Isolate* isolate);
263
264 virtual bool IsClosed() const { return (current_instruction_ == NULL); }
265
266 virtual intptr_t stack_limit_slack();
267 virtual void AdvanceCurrentPosition(intptr_t by);
268 virtual void AdvanceRegister(intptr_t reg, intptr_t by);
269 virtual void Backtrack();
270 virtual void BindBlock(BlockLabel* label);
271 virtual void CheckAtStart(BlockLabel* on_at_start);
272 virtual void CheckCharacter(uint32_t c, BlockLabel* on_equal);
273 virtual void CheckCharacterAfterAnd(uint32_t c,
274 uint32_t mask,
275 BlockLabel* on_equal);
276 virtual void CheckCharacterGT(uint16_t limit, BlockLabel* on_greater);
277 virtual void CheckCharacterLT(uint16_t limit, BlockLabel* on_less);
278 // A "greedy loop" is a loop that is both greedy and with a simple
279 // body. It has a particularly simple implementation.
280 virtual void CheckGreedyLoop(BlockLabel* on_tos_equals_current_position);
281 virtual void CheckNotAtStart(BlockLabel* on_not_at_start);
282 virtual void CheckNotBackReference(intptr_t start_reg,
283 BlockLabel* on_no_match);
284 virtual void CheckNotBackReferenceIgnoreCase(intptr_t start_reg,
285 BlockLabel* on_no_match);
286 virtual void CheckNotCharacter(uint32_t c, BlockLabel* on_not_equal);
287 virtual void CheckNotCharacterAfterAnd(uint32_t c,
288 uint32_t mask,
289 BlockLabel* on_not_equal);
290 virtual void CheckNotCharacterAfterMinusAnd(uint16_t c,
291 uint16_t minus,
292 uint16_t mask,
293 BlockLabel* on_not_equal);
294 virtual void CheckCharacterInRange(uint16_t from,
295 uint16_t to,
296 BlockLabel* on_in_range);
297 virtual void CheckCharacterNotInRange(uint16_t from,
298 uint16_t to,
299 BlockLabel* on_not_in_range);
300 virtual void CheckBitInTable(const TypedData& table, BlockLabel* on_bit_set);
301
302 // Checks whether the given offset from the current position is before
303 // the end of the string.
304 virtual void CheckPosition(intptr_t cp_offset, BlockLabel* on_outside_input);
305 virtual bool CheckSpecialCharacterClass(
306 uint16_t type, BlockLabel* on_no_match);
307 virtual void Fail();
308 virtual void GoTo(BlockLabel* to);
309 virtual void IfRegisterGE(intptr_t reg,
310 intptr_t comparand, BlockLabel* if_ge);
311 virtual void IfRegisterLT(intptr_t reg,
312 intptr_t comparand, BlockLabel* if_lt);
313 virtual void IfRegisterEqPos(intptr_t reg, BlockLabel* if_eq);
314 virtual IrregexpImplementation Implementation();
315 virtual void Jump(BlockLabel* to);
316 virtual void LoadCurrentCharacter(intptr_t cp_offset,
317 BlockLabel* on_end_of_input,
318 bool check_bounds = true,
319 intptr_t characters = 1);
320 virtual void PopCurrentPosition();
321 virtual void PopRegister(intptr_t register_index);
322 virtual void Print(const char* str);
323 virtual void PushBacktrack(BlockLabel* label);
324 virtual void PushCurrentPosition();
325 virtual void PushRegister(intptr_t register_index,
326 StackCheckFlag check_stack_limit);
327 virtual void ReadCurrentPositionFromRegister(intptr_t reg);
328 virtual void ReadStackPointerFromRegister(intptr_t reg);
329 virtual void SetCurrentPositionFromEnd(intptr_t by);
330 virtual void SetRegister(intptr_t register_index, intptr_t to);
331 virtual bool Succeed();
332 virtual void WriteCurrentPositionToRegister(intptr_t reg, intptr_t cp_offset);
333 virtual void ClearRegisters(intptr_t reg_from, intptr_t reg_to);
334 virtual void WriteStackPointerToRegister(intptr_t reg);
335
336 virtual void PrintBlocks();
337
338 GraphEntryInstr* graph_entry() const { return entry_block_; }
339
340 intptr_t num_stack_locals() const { return local_id.Count(); }
341 intptr_t num_blocks() const { return block_id.Count(); }
342
343 // A table mapping block ids to block offsets, used to look up offsets
344 // for indirect goto instructions.
345 void FinalizeBlockOffsetTable();
346
347 // Fill in indirect goto successors.
348 void FinalizeIndirectGotos();
349
350 private:
351 // Generate the contents of preset blocks. The entry block is the entry point
352 // of the generated code.
353 void GenerateEntryBlock();
354 // Performs backtracking, i.e. popping an offset from the stack and doing
355 // an indirect goto.
356 void GenerateBacktrackBlock();
357 // Copies capture indices into the result area and returns true.
358 void GenerateSuccessBlock();
359 // Returns false.
360 void GenerateExitBlock();
361
362 enum ComparisonKind {
363 kEQ,
364 kNE,
365 kLT,
366 kGT,
367 kLTE,
368 kGTE,
369 };
370
371 struct InstanceCallDescriptor : public ValueObject {
372 // Standard (i.e. most non-Smi) functions.
373 explicit InstanceCallDescriptor(const String& name)
374 : name(&name),
375 token_kind(Token::kILLEGAL),
376 checked_argument_count(1) { }
377
378 // Special cases for Smi and indexing functions.
379 explicit InstanceCallDescriptor(Token::Kind token_kind)
380 : token_kind(token_kind) {
381 switch (token_kind) {
382 case Token::kEQ:
383 name = &Symbols::EqualOperator();
384 checked_argument_count = 2;
385 break;
386 case Token::kADD:
387 name = &Symbols::Plus();
388 checked_argument_count = 2;
389 break;
390 case Token::kSUB:
391 name = &Symbols::Minus();
392 checked_argument_count = 2;
393 break;
394 case Token::kBIT_OR:
395 name = &Symbols::BitOr();
396 checked_argument_count = 2;
397 break;
398 case Token::kBIT_AND:
399 name = &Symbols::BitAnd();
400 checked_argument_count = 2;
401 break;
402 case Token::kLT:
403 name = &Symbols::LAngleBracket();
404 checked_argument_count = 2;
405 break;
406 case Token::kLTE:
407 name = &Symbols::LessEqualOperator();
408 checked_argument_count = 2;
409 break;
410 case Token::kGT:
411 name = &Symbols::RAngleBracket();
412 checked_argument_count = 2;
413 break;
414 case Token::kGTE:
415 name = &Symbols::GreaterEqualOperator();
416 checked_argument_count = 2;
417 break;
418 case Token::kNEGATE:
419 name = &Symbols::UnaryMinus();
420 checked_argument_count = 1;
421 break;
422 case Token::kINDEX:
423 name = &Symbols::IndexToken();
424 checked_argument_count = 2;
425 break;
426 case Token::kASSIGN_INDEX:
427 name = &Symbols::AssignIndexToken();
428 checked_argument_count = 3;
429 break;
430 default:
431 UNREACHABLE();
432 }
433 }
434
435 InstanceCallDescriptor(const InstanceCallDescriptor& that)
436 : ValueObject(),
437 name(that.name),
438 token_kind(that.token_kind),
439 checked_argument_count(that.checked_argument_count) { }
440
441 const String* name;
442 Token::Kind token_kind;
443 intptr_t checked_argument_count;
444 };
445
446 LocalVariable* Local(const String& name);
447 LocalVariable* Parameter(const String& name, intptr_t index) const;
448
449 ConstantInstr* Int64Constant(int64_t value) const;
450 ConstantInstr* Uint64Constant(uint64_t value) const;
451 ConstantInstr* BoolConstant(bool value) const;
452 ConstantInstr* StringConstant(const char* value) const;
453
454 // The word character map static member of the RegExp class.
455 // Byte map of one byte characters with a 0xff if the character is a word
456 // character (digit, letter or underscore) and 0x00 otherwise.
457 // Used by generated RegExp code.
458 ConstantInstr* WordCharacterMapConstant() const;
459
460 ComparisonInstr* Comparison(ComparisonKind kind,
461 Definition* lhs, Definition* rhs);
462
463 InstanceCallInstr* InstanceCall(const InstanceCallDescriptor& desc,
464 PushArgumentInstr* arg1) const;
465 InstanceCallInstr* InstanceCall(const InstanceCallDescriptor& desc,
466 PushArgumentInstr* arg1,
467 PushArgumentInstr* arg2) const;
468 InstanceCallInstr* InstanceCall(const InstanceCallDescriptor& desc,
469 PushArgumentInstr* arg1,
470 PushArgumentInstr* arg2,
471 PushArgumentInstr* arg3) const;
472 InstanceCallInstr* InstanceCall(
473 const InstanceCallDescriptor& desc,
474 ZoneGrowableArray<PushArgumentInstr*>* arguments) const;
475
476 StaticCallInstr* StaticCall(const Function& function) const;
477 StaticCallInstr* StaticCall(const Function& function,
478 PushArgumentInstr* arg1) const;
479 StaticCallInstr* StaticCall(const Function& function,
480 PushArgumentInstr* arg1,
481 PushArgumentInstr* arg2) const;
482 StaticCallInstr* StaticCall(
483 const Function& function,
484 ZoneGrowableArray<PushArgumentInstr*>* arguments) const;
485
486 // Creates a new block consisting simply of a goto to dst.
487 TargetEntryInstr* TargetWithJoinGoto(JoinEntryInstr* dst);
488 IndirectEntryInstr* IndirectWithJoinGoto(JoinEntryInstr* dst);
489
490 // Adds, respectively subtracts lhs and rhs and returns the result.
491 Value* Add(PushArgumentInstr* lhs, PushArgumentInstr* rhs);
492 Value* Sub(PushArgumentInstr* lhs, PushArgumentInstr* rhs);
493
494 LoadLocalInstr* LoadLocal(LocalVariable* local) const;
495 void StoreLocal(LocalVariable* local, Value* value);
496
497 PushArgumentInstr* PushArgument(Value* value);
498
499 // Returns the character within the passed string at the specified index.
500 Value* CharacterAt(Definition* index);
501
502 // Load a number of characters at the given offset from the
503 // current position, into the current-character register.
504 void LoadCurrentCharacterUnchecked(intptr_t cp_offset,
505 intptr_t character_count);
506
507 // Check whether preemption has been requested.
508 void CheckPreemption();
509
510 // Byte size of chars in the string to match (decided by the Mode argument)
511 inline intptr_t char_size() { return static_cast<int>(mode_); }
512
513 // Equivalent to a conditional branch to the label, unless the label
514 // is NULL, in which case it is a conditional Backtrack.
515 void BranchOrBacktrack(ComparisonInstr* comparison,
516 BlockLabel* true_successor);
517
518 // Set up all local variables and parameters.
519 void InitializeLocals();
520
521 // Allocates a new local, and returns the appropriate id for placing it
522 // on the stack.
523 intptr_t GetNextLocalIndex();
524
525 // We never have any copied parameters.
526 intptr_t num_copied_params() const {
527 return 0;
528 }
529
530 // Return the position register at the specified index, creating it if
531 // necessary. Note that the number of such registers can exceed the amount
532 // required by the number of output captures.
533 LocalVariable* position_register(intptr_t index);
534
535 void set_current_instruction(Instruction* instruction);
536
537 // The following functions are responsible for appending instructions
538 // to the current instruction in various ways. The most simple one
539 // is AppendInstruction, which simply appends an instruction and performs
540 // bookkeeping.
541 void AppendInstruction(Instruction* instruction);
542 // Similar to AppendInstruction, but closes the current block by
543 // setting current_instruction_ to NULL.
544 void CloseBlockWith(Instruction* instruction);
545 // Appends definition and allocates a temp index for the result.
546 Value* Bind(Definition* definition);
547 // Appends the definition.
548 void Do(Definition* definition);
549 // Closes the current block with a jump to the specified block.
550 void Jump(JoinEntryInstr* to);
551
552 // Accessors for our local stack_.
553 void PushStack(Definition* definition);
554 Value* PopStack();
555
556 // Prints the specified argument. Used for debugging.
557 void Print(PushArgumentInstr* argument);
558
559 // A utility class tracking ids of various objects such as blocks, temps, etc.
560 class IdAllocator : public ValueObject {
561 public:
562 IdAllocator() : next_id(0) { }
563
564 intptr_t Count() const { return next_id; }
565 intptr_t Alloc(intptr_t count = 1) {
566 ASSERT(count >= 0);
567 intptr_t current_id = next_id;
568 next_id += count;
569 return current_id;
570 }
571 void Dealloc(intptr_t count = 1) {
572 ASSERT(count <= next_id);
573 next_id -= count;
574 }
575
576 private:
577 intptr_t next_id;
578 };
579
580 // Which mode to generate code for (ASCII or UC16).
581 Mode mode_;
582
583 // Which specific string class to generate code for.
584 intptr_t specialization_cid_;
585
586 // Block entries used internally.
587 GraphEntryInstr* entry_block_;
588 JoinEntryInstr* start_block_;
589 JoinEntryInstr* success_block_;
590 JoinEntryInstr* backtrack_block_;
591 JoinEntryInstr* exit_block_;
592
593 const ParsedFunction* parsed_function_;
594 ZoneGrowableArray<const ICData*>* ic_data_array_;
595
596 // All created blocks are contained within this set. Used for printing
597 // the generated code.
598 GrowableArray<BlockEntryInstr*> blocks_;
599
600 // The current instruction to link to when new code is emitted.
601 Instruction* current_instruction_;
602
603 // A list, acting as the runtime stack for both backtrack locations and
604 // stored positions within the string.
605 LocalVariable* stack_;
606
607 // Stores the current character within the string.
608 LocalVariable* current_character_;
609
610 // Stores the current location within the string as a negative offset
611 // from the end of the string.
612 LocalVariable* current_position_;
613
614 // The string being processed, passed as a function parameter.
615 LocalVariable* string_param_;
616
617 // Stores the length of string_param_.
618 LocalVariable* string_param_length_;
619
620 // The start index within the string, passed as a function parameter.
621 LocalVariable* start_index_param_;
622
623 // An assortment of utility variables.
624 LocalVariable* capture_length_;
625 LocalVariable* match_start_index_;
626 LocalVariable* capture_start_index_;
627 LocalVariable* match_end_index_;
628 LocalVariable* char_in_capture_;
629 LocalVariable* char_in_match_;
630
631 LocalVariable* result_;
632
633 // Stored positions containing group bounds. Generated as needed.
634 const intptr_t position_registers_count_;
635 GrowableArray<LocalVariable*> position_registers_;
636
637 // The actual array object used as the stack.
638 GrowableObjectArray& stack_array_;
639
640 GrowableArray<IndirectGotoInstr*> igotos_;
641
642 IdAllocator block_id;
643 IdAllocator temp_id;
644 IdAllocator arg_id;
645 IdAllocator local_id;
646 };
647
648 } // namespace dart
649
650 #endif // VM_REGEXP_ASSEMBLER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698