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

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

Issue 837503002: Replace the use of local variables for irregexp registers by a typed array. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 11 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
« no previous file with comments | « runtime/vm/regexp_assembler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 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 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.h" 5 #include "vm/regexp_assembler.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/compiler.h" 8 #include "vm/compiler.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 * negative offset from the end of the string (i.e. the 55 * negative offset from the end of the string (i.e. the
56 * position corresponding to str[0] is -str.length). 56 * position corresponding to str[0] is -str.length).
57 * Note that current_position_ is *not* byte-based, unlike 57 * Note that current_position_ is *not* byte-based, unlike
58 * original V8 code. 58 * original V8 code.
59 * 59 *
60 * Results are returned though an array of capture indices, stored at 60 * Results are returned though an array of capture indices, stored at
61 * matches_param_. A null array specifies a failure to match. The match indices 61 * matches_param_. A null array specifies a failure to match. The match indices
62 * [start_inclusive, end_exclusive] for capture group i are stored at positions 62 * [start_inclusive, end_exclusive] for capture group i are stored at positions
63 * matches_param_[i * 2] and matches_param_[i * 2 + 1], respectively. Match 63 * matches_param_[i * 2] and matches_param_[i * 2 + 1], respectively. Match
64 * indices of -1 denote non-matched groups. Note that we store these indices 64 * indices of -1 denote non-matched groups. Note that we store these indices
65 * as a negative offset from the end of the string in position_registers_ 65 * as a negative offset from the end of the string in registers_array_
66 * during processing, and convert them to standard indexes when copying them 66 * during processing, and convert them to standard indexes when copying them
67 * to matches_param_ on successful match. 67 * to matches_param_ on successful match.
68 */ 68 */
69 69
70 RegExpMacroAssembler::RegExpMacroAssembler(Isolate* isolate) 70 RegExpMacroAssembler::RegExpMacroAssembler(Isolate* isolate)
71 : slow_safe_compiler_(false), 71 : slow_safe_compiler_(false),
72 global_mode_(NOT_GLOBAL), 72 global_mode_(NOT_GLOBAL),
73 isolate_(isolate) { 73 isolate_(isolate) {
74 } 74 }
75 75
(...skipping 12 matching lines...) Expand all
88 specialization_cid_(specialization_cid), 88 specialization_cid_(specialization_cid),
89 parsed_function_(parsed_function), 89 parsed_function_(parsed_function),
90 ic_data_array_(ic_data_array), 90 ic_data_array_(ic_data_array),
91 current_instruction_(NULL), 91 current_instruction_(NULL),
92 stack_(NULL), 92 stack_(NULL),
93 current_character_(NULL), 93 current_character_(NULL),
94 current_position_(NULL), 94 current_position_(NULL),
95 string_param_(NULL), 95 string_param_(NULL),
96 string_param_length_(NULL), 96 string_param_length_(NULL),
97 start_index_param_(NULL), 97 start_index_param_(NULL),
98 position_registers_count_((capture_count + 1) * 2), 98 registers_count_(0),
99 saved_registers_count_((capture_count + 1) * 2),
99 stack_array_(GrowableObjectArray::ZoneHandle( 100 stack_array_(GrowableObjectArray::ZoneHandle(
100 isolate, GrowableObjectArray::New(16, Heap::kOld))) { 101 isolate, GrowableObjectArray::New(16, Heap::kOld))),
102 // The registers array is allocated at a fixed size after assembly.
103 registers_array_(TypedData::ZoneHandle(isolate, TypedData::null())) {
101 switch (specialization_cid) { 104 switch (specialization_cid) {
102 case kOneByteStringCid: 105 case kOneByteStringCid:
103 case kExternalOneByteStringCid: mode_ = ASCII; break; 106 case kExternalOneByteStringCid: mode_ = ASCII; break;
104 case kTwoByteStringCid: 107 case kTwoByteStringCid:
105 case kExternalTwoByteStringCid: mode_ = UC16; break; 108 case kExternalTwoByteStringCid: mode_ = UC16; break;
106 default: UNREACHABLE(); 109 default: UNREACHABLE();
107 } 110 }
108 111
109 InitializeLocals(); 112 InitializeLocals();
110 113
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 IRRegExpMacroAssembler::~IRRegExpMacroAssembler() { } 145 IRRegExpMacroAssembler::~IRRegExpMacroAssembler() { }
143 146
144 147
145 void IRRegExpMacroAssembler::InitializeLocals() { 148 void IRRegExpMacroAssembler::InitializeLocals() {
146 // All generated functions are expected to have a current-context variable. 149 // All generated functions are expected to have a current-context variable.
147 // This variable is unused in irregexp functions. 150 // This variable is unused in irregexp functions.
148 parsed_function_->current_context_var()->set_index(GetNextLocalIndex()); 151 parsed_function_->current_context_var()->set_index(GetNextLocalIndex());
149 152
150 // Create local variables and parameters. 153 // Create local variables and parameters.
151 stack_ = Local(Symbols::stack()); 154 stack_ = Local(Symbols::stack());
155 registers_ = Local(Symbols::position_registers());
152 current_character_ = Local(Symbols::current_character()); 156 current_character_ = Local(Symbols::current_character());
153 current_position_ = Local(Symbols::current_position()); 157 current_position_ = Local(Symbols::current_position());
154 string_param_length_ = Local(Symbols::string_param_length()); 158 string_param_length_ = Local(Symbols::string_param_length());
155 capture_length_ = Local(Symbols::capture_length()); 159 capture_length_ = Local(Symbols::capture_length());
156 match_start_index_ = Local(Symbols::match_start_index()); 160 match_start_index_ = Local(Symbols::match_start_index());
157 capture_start_index_ = Local(Symbols::capture_start_index()); 161 capture_start_index_ = Local(Symbols::capture_start_index());
158 match_end_index_ = Local(Symbols::match_end_index()); 162 match_end_index_ = Local(Symbols::match_end_index());
159 char_in_capture_ = Local(Symbols::char_in_capture()); 163 char_in_capture_ = Local(Symbols::char_in_capture());
160 char_in_match_ = Local(Symbols::char_in_match()); 164 char_in_match_ = Local(Symbols::char_in_match());
161 index_temp_ = Local(Symbols::index_temp()); 165 index_temp_ = Local(Symbols::index_temp());
162 result_ = Local(Symbols::result()); 166 result_ = Local(Symbols::result());
163 167
164 string_param_ = Parameter(Symbols::string_param(), 0); 168 string_param_ = Parameter(Symbols::string_param(), 0);
165 start_index_param_ = Parameter(Symbols::start_index_param(), 1); 169 start_index_param_ = Parameter(Symbols::start_index_param(), 1);
166
167 // Reserve space for all captured group positions. Note that more might
168 // be created on the fly for internal use.
169 for (intptr_t i = 0; i < position_registers_count_; i++) {
170 position_register(i);
171 }
172 } 170 }
173 171
174 172
175 void IRRegExpMacroAssembler::GenerateEntryBlock() { 173 void IRRegExpMacroAssembler::GenerateEntryBlock() {
176 set_current_instruction(entry_block_->normal_entry()); 174 set_current_instruction(entry_block_->normal_entry());
177 TAG(); 175 TAG();
178 176
179 // Generate a local list variable which we will use as a backtracking stack.
180
181 StoreLocal(stack_, Bind(new(I) ConstantInstr(stack_array_)));
182 Do(InstanceCall(InstanceCallDescriptor(Symbols::clear()), PushLocal(stack_)));
183
184 // Store string.length. 177 // Store string.length.
185 PushArgumentInstr* string_push = PushLocal(string_param_); 178 PushArgumentInstr* string_push = PushLocal(string_param_);
186 179
187 StoreLocal( 180 StoreLocal(
188 string_param_length_, 181 string_param_length_,
189 Bind(InstanceCall( 182 Bind(InstanceCall(
190 InstanceCallDescriptor( 183 InstanceCallDescriptor(
191 String::ZoneHandle(Field::GetterSymbol(Symbols::Length()))), 184 String::ZoneHandle(Field::GetterSymbol(Symbols::Length()))),
192 string_push))); 185 string_push)));
193 186
194 // Initialize all capture registers.
195 ClearRegisters(0, position_registers_count_ - 1);
196
197 // Store (start_index - string.length) as the current position (since it's a 187 // Store (start_index - string.length) as the current position (since it's a
198 // negative offset from the end of the string). 188 // negative offset from the end of the string).
199 PushArgumentInstr* start_index_push = PushLocal(start_index_param_); 189 PushArgumentInstr* start_index_push = PushLocal(start_index_param_);
200 PushArgumentInstr* length_push = PushLocal(string_param_length_); 190 PushArgumentInstr* length_push = PushLocal(string_param_length_);
201 191
202 StoreLocal(current_position_, Bind(Sub(start_index_push, length_push))); 192 StoreLocal(current_position_, Bind(Sub(start_index_push, length_push)));
203 193
194 // Generate a local list variable to represent "registers" and
195 // initialize capture registers (others remain garbage).
196 StoreLocal(registers_, Bind(new(I) ConstantInstr(registers_array_)));
197 ClearRegisters(0, saved_registers_count_ - 1);
198
199 // Generate a local list variable to represent the backtracking stack.
200 StoreLocal(stack_, Bind(new(I) ConstantInstr(stack_array_)));
201 PushArgumentInstr* stack_push = PushLocal(stack_);
202 Do(InstanceCall(InstanceCallDescriptor(Symbols::clear()), stack_push));
203
204 // Jump to the start block. 204 // Jump to the start block.
205 current_instruction_->Goto(start_block_); 205 current_instruction_->Goto(start_block_);
206 } 206 }
207 207
208 208
209 void IRRegExpMacroAssembler::GenerateBacktrackBlock() { 209 void IRRegExpMacroAssembler::GenerateBacktrackBlock() {
210 set_current_instruction(backtrack_block_); 210 set_current_instruction(backtrack_block_);
211 TAG(); 211 TAG();
212 CheckPreemption(); 212 CheckPreemption();
213 213
(...skipping 19 matching lines...) Expand all
233 backtrack_goto_->AddSuccessor( 233 backtrack_goto_->AddSuccessor(
234 TargetWithJoinGoto(entry_block_->indirect_entries().At(j))); 234 TargetWithJoinGoto(entry_block_->indirect_entries().At(j)));
235 } 235 }
236 } 236 }
237 237
238 238
239 void IRRegExpMacroAssembler::GenerateSuccessBlock() { 239 void IRRegExpMacroAssembler::GenerateSuccessBlock() {
240 set_current_instruction(success_block_); 240 set_current_instruction(success_block_);
241 TAG(); 241 TAG();
242 242
243 Definition* type_args_null_def = new(I) ConstantInstr( 243 Value* type = Bind(new(I) ConstantInstr(
244 TypeArguments::ZoneHandle(I, TypeArguments::null())); 244 TypeArguments::ZoneHandle(I, TypeArguments::null())));
245 PushArgumentInstr* type_arg_push = PushArgument(Bind(type_args_null_def)); 245 Value* length = Bind(Uint64Constant(saved_registers_count_));
246 PushArgumentInstr* length_push = 246 Value* array = Bind(new(I) CreateArrayInstr(kNoSourcePos, type, length));
247 PushArgument(Bind(Uint64Constant(position_registers_count_))); 247 StoreLocal(result_, array);
248
249 const Library& lib = Library::Handle(Library::CoreLibrary());
250 const Class& list_class = Class::Handle(
251 lib.LookupCoreClass(Symbols::List()));
252 const Function& list_ctor =
253 Function::ZoneHandle(I, list_class.LookupFactory(Symbols::ListFactory()));
254
255 // TODO(zerny): Use CreateArrayInstr and StoreIndexed instead.
256 StoreLocal(result_, Bind(StaticCall(list_ctor, type_arg_push, length_push)));
257 248
258 // Store captured offsets in the `matches` parameter. 249 // Store captured offsets in the `matches` parameter.
259 // TODO(zerny): Eliminate position_register locals and access `matches` 250 for (intptr_t i = 0; i < saved_registers_count_; i++) {
260 // directly.
261 for (intptr_t i = 0; i < position_registers_count_; i++) {
262 PushArgumentInstr* matches_push = PushLocal(result_); 251 PushArgumentInstr* matches_push = PushLocal(result_);
263 PushArgumentInstr* index_push = PushArgument(Bind(Uint64Constant(i))); 252 PushArgumentInstr* index_push = PushArgument(Bind(Uint64Constant(i)));
264 253
265 // Convert negative offsets from the end of the string to string indices. 254 // Convert negative offsets from the end of the string to string indices.
266 PushArgumentInstr* offset_push = PushLocal(position_register(i)); 255 // TODO(zerny): use positive offsets from the get-go.
256 PushArgumentInstr* offset_push = PushArgument(LoadRegister(i));
267 PushArgumentInstr* len_push = PushLocal(string_param_length_); 257 PushArgumentInstr* len_push = PushLocal(string_param_length_);
268 PushArgumentInstr* value_push = 258 PushArgumentInstr* value_push =
269 PushArgument(Bind(Add(offset_push, len_push))); 259 PushArgument(Bind(Add(offset_push, len_push)));
270 260
271 Do(InstanceCall(InstanceCallDescriptor::FromToken(Token::kASSIGN_INDEX), 261 Do(InstanceCall(InstanceCallDescriptor::FromToken(Token::kASSIGN_INDEX),
272 matches_push, 262 matches_push,
273 index_push, 263 index_push,
274 value_push)); 264 value_push));
275 } 265 }
276 266
277 // Print the result if tracing. 267 // Print the result if tracing.
278 PRINT(PushLocal(result_)); 268 PRINT(PushLocal(result_));
279 269
280 // Return true on success. 270 // Return true on success.
281 AppendInstruction(new(I) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_)))); 271 AppendInstruction(new(I) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_))));
282 } 272 }
283 273
284 274
285 void IRRegExpMacroAssembler::GenerateExitBlock() { 275 void IRRegExpMacroAssembler::GenerateExitBlock() {
286 set_current_instruction(exit_block_); 276 set_current_instruction(exit_block_);
287 TAG(); 277 TAG();
288 278
289 // Return false on failure. 279 // Return false on failure.
290 AppendInstruction(new(I) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_)))); 280 AppendInstruction(new(I) ReturnInstr(kNoSourcePos, Bind(LoadLocal(result_))));
291 } 281 }
292 282
293 283
284 void IRRegExpMacroAssembler::FinalizeRegistersArray() {
285 ASSERT(registers_count_ >= saved_registers_count_);
286 registers_array_ =
287 TypedData::New(kTypedDataInt32ArrayCid, registers_count_, Heap::kOld);
288 }
289
290
294 #if defined(TARGET_ARCH_ARM64) || \ 291 #if defined(TARGET_ARCH_ARM64) || \
295 defined(TARGET_ARCH_ARM) || \ 292 defined(TARGET_ARCH_ARM) || \
296 defined(TARGET_ARCH_MIPS) 293 defined(TARGET_ARCH_MIPS)
297 // Disabling unaligned accesses forces the regexp engine to load characters one 294 // Disabling unaligned accesses forces the regexp engine to load characters one
298 // by one instead of up to 4 at once, along with the associated performance hit. 295 // by one instead of up to 4 at once, along with the associated performance hit.
299 // TODO(zerny): Be less conservative about disabling unaligned accesses. 296 // TODO(zerny): Be less conservative about disabling unaligned accesses.
300 // For instance, ARMv6 supports unaligned accesses. Once it is enabled here, 297 // For instance, ARMv6 supports unaligned accesses. Once it is enabled here,
301 // update LoadCodeUnitsInstr methods for the appropriate architectures. 298 // update LoadCodeUnitsInstr methods for the appropriate architectures.
302 static const bool kEnableUnalignedAccesses = false; 299 static const bool kEnableUnalignedAccesses = false;
303 #else 300 #else
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 word_character_field.EvaluateInitializer(); 426 word_character_field.EvaluateInitializer();
430 } 427 }
431 ASSERT(!word_character_field.IsUninitialized()); 428 ASSERT(!word_character_field.IsUninitialized());
432 429
433 return new(I) ConstantInstr( 430 return new(I) ConstantInstr(
434 Instance::ZoneHandle(I, word_character_field.value())); 431 Instance::ZoneHandle(I, word_character_field.value()));
435 } 432 }
436 433
437 434
438 ComparisonInstr* IRRegExpMacroAssembler::Comparison( 435 ComparisonInstr* IRRegExpMacroAssembler::Comparison(
439 ComparisonKind kind, Definition* lhs, Definition* rhs) { 436 ComparisonKind kind, PushArgumentInstr* lhs, PushArgumentInstr* rhs) {
440 Token::Kind strict_comparison = Token::kEQ_STRICT; 437 Token::Kind strict_comparison = Token::kEQ_STRICT;
441 Token::Kind intermediate_operator = Token::kILLEGAL; 438 Token::Kind intermediate_operator = Token::kILLEGAL;
442 switch (kind) { 439 switch (kind) {
443 case kEQ: 440 case kEQ:
444 intermediate_operator = Token::kEQ; 441 intermediate_operator = Token::kEQ;
445 break; 442 break;
446 case kNE: 443 case kNE:
447 intermediate_operator = Token::kEQ; 444 intermediate_operator = Token::kEQ;
448 strict_comparison = Token::kNE_STRICT; 445 strict_comparison = Token::kNE_STRICT;
449 break; 446 break;
450 case kLT: 447 case kLT:
451 intermediate_operator = Token::kLT; 448 intermediate_operator = Token::kLT;
452 break; 449 break;
453 case kGT: 450 case kGT:
454 intermediate_operator = Token::kGT; 451 intermediate_operator = Token::kGT;
455 break; 452 break;
456 case kLTE: 453 case kLTE:
457 intermediate_operator = Token::kLTE; 454 intermediate_operator = Token::kLTE;
458 break; 455 break;
459 case kGTE: 456 case kGTE:
460 intermediate_operator = Token::kGTE; 457 intermediate_operator = Token::kGTE;
461 break; 458 break;
462 default: 459 default:
463 UNREACHABLE(); 460 UNREACHABLE();
464 } 461 }
465 462
466 ASSERT(intermediate_operator != Token::kILLEGAL); 463 ASSERT(intermediate_operator != Token::kILLEGAL);
467 464
468 PushArgumentInstr* lhs_push = PushArgument(Bind(lhs));
469 PushArgumentInstr* rhs_push = PushArgument(Bind(rhs));
470
471 Value* lhs_value = 465 Value* lhs_value =
472 Bind(InstanceCall( 466 Bind(InstanceCall(
473 InstanceCallDescriptor::FromToken(intermediate_operator), 467 InstanceCallDescriptor::FromToken(intermediate_operator),
474 lhs_push, 468 lhs,
475 rhs_push)); 469 rhs));
476 Value* rhs_value = Bind(BoolConstant(true)); 470 Value* rhs_value = Bind(BoolConstant(true));
477 471
478 return new(I) StrictCompareInstr( 472 return new(I) StrictCompareInstr(
479 kNoSourcePos, strict_comparison, lhs_value, rhs_value, true); 473 kNoSourcePos, strict_comparison, lhs_value, rhs_value, true);
480 } 474 }
481 475
476 ComparisonInstr* IRRegExpMacroAssembler::Comparison(
477 ComparisonKind kind, Definition* lhs, Definition* rhs) {
478 PushArgumentInstr* lhs_push = PushArgument(Bind(lhs));
479 PushArgumentInstr* rhs_push = PushArgument(Bind(rhs));
480 return Comparison(kind, lhs_push, rhs_push);
481 }
482
482 483
483 StaticCallInstr* IRRegExpMacroAssembler::StaticCall( 484 StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
484 const Function& function) const { 485 const Function& function) const {
485 ZoneGrowableArray<PushArgumentInstr*>* arguments = 486 ZoneGrowableArray<PushArgumentInstr*>* arguments =
486 new(I) ZoneGrowableArray<PushArgumentInstr*>(0); 487 new(I) ZoneGrowableArray<PushArgumentInstr*>(0);
487 return StaticCall(function, arguments); 488 return StaticCall(function, arguments);
488 } 489 }
489 490
490 491
491 StaticCallInstr* IRRegExpMacroAssembler::StaticCall( 492 StaticCallInstr* IRRegExpMacroAssembler::StaticCall(
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
728 729
729 Value* new_pos_value = Bind(Add(cur_pos_push, by_push)); 730 Value* new_pos_value = Bind(Add(cur_pos_push, by_push));
730 StoreLocal(current_position_, new_pos_value); 731 StoreLocal(current_position_, new_pos_value);
731 } 732 }
732 } 733 }
733 734
734 735
735 void IRRegExpMacroAssembler::AdvanceRegister(intptr_t reg, intptr_t by) { 736 void IRRegExpMacroAssembler::AdvanceRegister(intptr_t reg, intptr_t by) {
736 TAG(); 737 TAG();
737 ASSERT(reg >= 0); 738 ASSERT(reg >= 0);
738 ASSERT(reg < position_registers_.length()); 739 ASSERT(reg < registers_count_);
739 740
740 if (by != 0) { 741 if (by != 0) {
741 PushArgumentInstr* reg_push = PushLocal(position_register(reg)); 742 PushArgumentInstr* registers_push = PushLocal(registers_);
743 PushArgumentInstr* index_push = PushRegisterIndex(reg);
744 PushArgumentInstr* reg_push = PushArgument(LoadRegister(reg));
742 PushArgumentInstr* by_push = PushArgument(Bind(Int64Constant(by))); 745 PushArgumentInstr* by_push = PushArgument(Bind(Int64Constant(by)));
743 StoreLocal(position_register(reg), Bind(Add(reg_push, by_push))); 746 PushArgumentInstr* value_push = PushArgument(Bind(Add(reg_push, by_push)));
747 StoreRegister(registers_push, index_push, value_push);
744 } 748 }
745 } 749 }
746 750
747 751
748 void IRRegExpMacroAssembler::Backtrack() { 752 void IRRegExpMacroAssembler::Backtrack() {
749 TAG(); 753 TAG();
750 GoTo(backtrack_block_); 754 GoTo(backtrack_block_);
751 } 755 }
752 756
753 757
(...skipping 16 matching lines...) Expand all
770 PRINT(PushArgument(Bind(Uint64Constant(label->block()->block_id())))); 774 PRINT(PushArgument(Bind(Uint64Constant(label->block()->block_id()))));
771 } 775 }
772 776
773 777
774 intptr_t IRRegExpMacroAssembler::GetNextLocalIndex() { 778 intptr_t IRRegExpMacroAssembler::GetNextLocalIndex() {
775 intptr_t id = local_id_.Alloc(); 779 intptr_t id = local_id_.Alloc();
776 return kFirstLocalSlotFromFp - id; 780 return kFirstLocalSlotFromFp - id;
777 } 781 }
778 782
779 783
780 LocalVariable* IRRegExpMacroAssembler::position_register(intptr_t index) { 784 Value* IRRegExpMacroAssembler::LoadRegister(intptr_t index) {
781 // Create position registers as needed. 785 PushArgumentInstr* registers_push = PushLocal(registers_);
782 for (intptr_t i = position_registers_.length(); i < index + 1; i++) { 786 PushArgumentInstr* index_push = PushRegisterIndex(index);
783 position_registers_.Add(Local(Symbols::position_registers())); 787 return Bind(InstanceCall(InstanceCallDescriptor::FromToken(Token::kINDEX),
784 } 788 registers_push,
789 index_push));
790 }
785 791
786 return position_registers_[index]; 792 void IRRegExpMacroAssembler::StoreRegister(intptr_t index, intptr_t value) {
793 PushArgumentInstr* registers_push = PushLocal(registers_);
794 PushArgumentInstr* index_push = PushRegisterIndex(index);
795 PushArgumentInstr* value_push = PushArgument(Bind(Uint64Constant(value)));
796 StoreRegister(registers_push, index_push, value_push);
787 } 797 }
788 798
789 799
800 void IRRegExpMacroAssembler::StoreRegister(PushArgumentInstr* registers,
801 PushArgumentInstr* index,
802 PushArgumentInstr* value) {
803 TAG();
804 Do(InstanceCall(InstanceCallDescriptor::FromToken(Token::kASSIGN_INDEX),
805 registers,
806 index,
807 value));
808 }
809
810 PushArgumentInstr* IRRegExpMacroAssembler::PushRegisterIndex(intptr_t index) {
811 if (registers_count_ <= index) {
812 registers_count_ = index + 1;
813 }
814 return PushArgument(Bind(Uint64Constant(index)));
815 }
816
817
790 void IRRegExpMacroAssembler::CheckCharacter(uint32_t c, BlockLabel* on_equal) { 818 void IRRegExpMacroAssembler::CheckCharacter(uint32_t c, BlockLabel* on_equal) {
791 TAG(); 819 TAG();
792 Definition* cur_char_def = LoadLocal(current_character_); 820 Definition* cur_char_def = LoadLocal(current_character_);
793 Definition* char_def = Uint64Constant(c); 821 Definition* char_def = Uint64Constant(c);
794 822
795 BranchOrBacktrack(Comparison(kEQ, cur_char_def, char_def), on_equal); 823 BranchOrBacktrack(Comparison(kEQ, cur_char_def, char_def), on_equal);
796 } 824 }
797 825
798 826
799 void IRRegExpMacroAssembler::CheckCharacterGT(uint16_t limit, 827 void IRRegExpMacroAssembler::CheckCharacterGT(uint16_t limit,
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 BranchOrBacktrack(NULL, on_equal); 911 BranchOrBacktrack(NULL, on_equal);
884 912
885 BindBlock(&fallthrough); 913 BindBlock(&fallthrough);
886 } 914 }
887 915
888 916
889 void IRRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase( 917 void IRRegExpMacroAssembler::CheckNotBackReferenceIgnoreCase(
890 intptr_t start_reg, 918 intptr_t start_reg,
891 BlockLabel* on_no_match) { 919 BlockLabel* on_no_match) {
892 TAG(); 920 TAG();
893 ASSERT(start_reg + 1 <= position_registers_.length()); 921 ASSERT(start_reg + 1 <= registers_count_);
894 922
895 BlockLabel fallthrough; 923 BlockLabel fallthrough;
896 924
897 PushArgumentInstr* end_push = PushLocal(position_register(start_reg + 1)); 925 PushArgumentInstr* end_push = PushArgument(LoadRegister(start_reg + 1));
898 PushArgumentInstr* start_push = PushLocal(position_register(start_reg)); 926 PushArgumentInstr* start_push = PushArgument(LoadRegister(start_reg));
899 StoreLocal(capture_length_, Bind(Sub(end_push, start_push))); 927 StoreLocal(capture_length_, Bind(Sub(end_push, start_push)));
900 928
901 // The length of a capture should not be negative. This can only happen 929 // The length of a capture should not be negative. This can only happen
902 // if the end of the capture is unrecorded, or at a point earlier than 930 // if the end of the capture is unrecorded, or at a point earlier than
903 // the start of the capture. 931 // the start of the capture.
904 // BranchOrBacktrack(less, on_no_match); 932 // BranchOrBacktrack(less, on_no_match);
905 933
906 BranchOrBacktrack(Comparison(kLT, 934 BranchOrBacktrack(Comparison(kLT,
907 LoadLocal(capture_length_), 935 LoadLocal(capture_length_),
908 Uint64Constant(0)), 936 Uint64Constant(0)),
(...skipping 15 matching lines...) Expand all
924 InstanceCall(InstanceCallDescriptor::FromToken(Token::kADD), 952 InstanceCall(InstanceCallDescriptor::FromToken(Token::kADD),
925 pos_push, 953 pos_push,
926 len_push), 954 len_push),
927 Uint64Constant(0)), 955 Uint64Constant(0)),
928 on_no_match); 956 on_no_match);
929 957
930 pos_push = PushLocal(current_position_); 958 pos_push = PushLocal(current_position_);
931 len_push = PushLocal(string_param_length_); 959 len_push = PushLocal(string_param_length_);
932 StoreLocal(match_start_index_, Bind(Add(pos_push, len_push))); 960 StoreLocal(match_start_index_, Bind(Add(pos_push, len_push)));
933 961
934 pos_push = PushLocal(position_register(start_reg)); 962 pos_push = PushArgument(LoadRegister(start_reg));
935 len_push = PushLocal(string_param_length_); 963 len_push = PushLocal(string_param_length_);
936 StoreLocal(capture_start_index_, Bind(Add(pos_push, len_push))); 964 StoreLocal(capture_start_index_, Bind(Add(pos_push, len_push)));
937 965
938 pos_push = PushLocal(match_start_index_); 966 pos_push = PushLocal(match_start_index_);
939 len_push = PushLocal(capture_length_); 967 len_push = PushLocal(capture_length_);
940 StoreLocal(match_end_index_, Bind(Add(pos_push, len_push))); 968 StoreLocal(match_end_index_, Bind(Add(pos_push, len_push)));
941 969
942 BlockLabel success; 970 BlockLabel success;
943 if (mode_ == ASCII) { 971 if (mode_ == ASCII) {
944 BlockLabel loop_increment; 972 BlockLabel loop_increment;
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1050 StoreLocal(current_position_, Bind(Sub(match_end_push, len_push))); 1078 StoreLocal(current_position_, Bind(Sub(match_end_push, len_push)));
1051 1079
1052 BindBlock(&fallthrough); 1080 BindBlock(&fallthrough);
1053 } 1081 }
1054 1082
1055 1083
1056 void IRRegExpMacroAssembler::CheckNotBackReference( 1084 void IRRegExpMacroAssembler::CheckNotBackReference(
1057 intptr_t start_reg, 1085 intptr_t start_reg,
1058 BlockLabel* on_no_match) { 1086 BlockLabel* on_no_match) {
1059 TAG(); 1087 TAG();
1060 ASSERT(start_reg + 1 <= position_registers_.length()); 1088 ASSERT(start_reg + 1 <= registers_count_);
1061 1089
1062 BlockLabel fallthrough; 1090 BlockLabel fallthrough;
1063 BlockLabel success; 1091 BlockLabel success;
1064 1092
1065 // Find length of back-referenced capture. 1093 // Find length of back-referenced capture.
1066 PushArgumentInstr* end_push = PushLocal(position_register(start_reg + 1)); 1094 PushArgumentInstr* end_push = PushArgument(LoadRegister(start_reg + 1));
1067 PushArgumentInstr* start_push = PushLocal(position_register(start_reg)); 1095 PushArgumentInstr* start_push = PushArgument(LoadRegister(start_reg));
1068 StoreLocal(capture_length_, Bind(Sub(end_push, start_push))); 1096 StoreLocal(capture_length_, Bind(Sub(end_push, start_push)));
1069 1097
1070 // Fail on partial or illegal capture (start of capture after end of capture). 1098 // Fail on partial or illegal capture (start of capture after end of capture).
1071 BranchOrBacktrack(Comparison(kLT, 1099 BranchOrBacktrack(Comparison(kLT,
1072 LoadLocal(capture_length_), 1100 LoadLocal(capture_length_),
1073 Uint64Constant(0)), 1101 Uint64Constant(0)),
1074 on_no_match); 1102 on_no_match);
1075 1103
1076 // Succeed on empty capture (including no capture) 1104 // Succeed on empty capture (including no capture)
1077 BranchOrBacktrack(Comparison(kEQ, 1105 BranchOrBacktrack(Comparison(kEQ,
(...skipping 10 matching lines...) Expand all
1088 pos_push, 1116 pos_push,
1089 len_push), 1117 len_push),
1090 Uint64Constant(0)), 1118 Uint64Constant(0)),
1091 on_no_match); 1119 on_no_match);
1092 1120
1093 // Compute pointers to match string and capture string. 1121 // Compute pointers to match string and capture string.
1094 pos_push = PushLocal(current_position_); 1122 pos_push = PushLocal(current_position_);
1095 len_push = PushLocal(string_param_length_); 1123 len_push = PushLocal(string_param_length_);
1096 StoreLocal(match_start_index_, Bind(Add(pos_push, len_push))); 1124 StoreLocal(match_start_index_, Bind(Add(pos_push, len_push)));
1097 1125
1098 pos_push = PushLocal(position_register(start_reg)); 1126 pos_push = PushArgument(LoadRegister(start_reg));
1099 len_push = PushLocal(string_param_length_); 1127 len_push = PushLocal(string_param_length_);
1100 StoreLocal(capture_start_index_, Bind(Add(pos_push, len_push))); 1128 StoreLocal(capture_start_index_, Bind(Add(pos_push, len_push)));
1101 1129
1102 pos_push = PushLocal(match_start_index_); 1130 pos_push = PushLocal(match_start_index_);
1103 len_push = PushLocal(capture_length_); 1131 len_push = PushLocal(capture_length_);
1104 StoreLocal(match_end_index_, Bind(Add(pos_push, len_push))); 1132 StoreLocal(match_end_index_, Bind(Add(pos_push, len_push)));
1105 1133
1106 BlockLabel loop; 1134 BlockLabel loop;
1107 BindBlock(&loop); 1135 BindBlock(&loop);
1108 1136
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 UNREACHABLE(); // Dart regexps are always global. 1469 UNREACHABLE(); // Dart regexps are always global.
1442 } 1470 }
1443 GoTo(exit_block_); 1471 GoTo(exit_block_);
1444 } 1472 }
1445 1473
1446 1474
1447 void IRRegExpMacroAssembler::IfRegisterGE(intptr_t reg, 1475 void IRRegExpMacroAssembler::IfRegisterGE(intptr_t reg,
1448 intptr_t comparand, 1476 intptr_t comparand,
1449 BlockLabel* if_ge) { 1477 BlockLabel* if_ge) {
1450 TAG(); 1478 TAG();
1451 BranchOrBacktrack(Comparison(kGTE, 1479 PushArgumentInstr* reg_push = PushArgument(LoadRegister(reg));
1452 LoadLocal(position_register(reg)), 1480 PushArgumentInstr* pos = PushArgument(Bind(Int64Constant(comparand)));
1453 Int64Constant(comparand)), 1481 BranchOrBacktrack(Comparison(kGTE, reg_push, pos), if_ge);
1454 if_ge);
1455 } 1482 }
1456 1483
1457 1484
1458 void IRRegExpMacroAssembler::IfRegisterLT(intptr_t reg, 1485 void IRRegExpMacroAssembler::IfRegisterLT(intptr_t reg,
1459 intptr_t comparand, 1486 intptr_t comparand,
1460 BlockLabel* if_lt) { 1487 BlockLabel* if_lt) {
1461 TAG(); 1488 TAG();
1462 BranchOrBacktrack(Comparison(kLT, 1489 PushArgumentInstr* reg_push = PushArgument(LoadRegister(reg));
1463 LoadLocal(position_register(reg)), 1490 PushArgumentInstr* pos = PushArgument(Bind(Int64Constant(comparand)));
1464 Int64Constant(comparand)), 1491 BranchOrBacktrack(Comparison(kLT, reg_push, pos), if_lt);
1465 if_lt);
1466 } 1492 }
1467 1493
1468 1494
1469 void IRRegExpMacroAssembler::IfRegisterEqPos(intptr_t reg, 1495 void IRRegExpMacroAssembler::IfRegisterEqPos(intptr_t reg,
1470 BlockLabel* if_eq) { 1496 BlockLabel* if_eq) {
1471 TAG(); 1497 TAG();
1472 BranchOrBacktrack(Comparison(kEQ, 1498 PushArgumentInstr* reg_push = PushArgument(LoadRegister(reg));
1473 LoadLocal(position_register(reg)), 1499 PushArgumentInstr* pos = PushArgument(Bind(LoadLocal(current_position_)));
1474 LoadLocal(current_position_)), 1500 BranchOrBacktrack(Comparison(kEQ, reg_push, pos), if_eq);
1475 if_eq);
1476 } 1501 }
1477 1502
1478 1503
1479 RegExpMacroAssembler::IrregexpImplementation 1504 RegExpMacroAssembler::IrregexpImplementation
1480 IRRegExpMacroAssembler::Implementation() { 1505 IRRegExpMacroAssembler::Implementation() {
1481 return kIRImplementation; 1506 return kIRImplementation;
1482 } 1507 }
1483 1508
1484 1509
1485 void IRRegExpMacroAssembler::LoadCurrentCharacter(intptr_t cp_offset, 1510 void IRRegExpMacroAssembler::LoadCurrentCharacter(intptr_t cp_offset,
1486 BlockLabel* on_end_of_input, 1511 BlockLabel* on_end_of_input,
1487 bool check_bounds, 1512 bool check_bounds,
1488 intptr_t characters) { 1513 intptr_t characters) {
1489 TAG(); 1514 TAG();
1490 ASSERT(cp_offset >= -1); // ^ and \b can look behind one character. 1515 ASSERT(cp_offset >= -1); // ^ and \b can look behind one character.
1491 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works) 1516 ASSERT(cp_offset < (1<<30)); // Be sane! (And ensure negation works)
1492 if (check_bounds) { 1517 if (check_bounds) {
1493 CheckPosition(cp_offset + characters - 1, on_end_of_input); 1518 CheckPosition(cp_offset + characters - 1, on_end_of_input);
1494 } 1519 }
1495 LoadCurrentCharacterUnchecked(cp_offset, characters); 1520 LoadCurrentCharacterUnchecked(cp_offset, characters);
1496 } 1521 }
1497 1522
1498 1523
1499 void IRRegExpMacroAssembler::PopCurrentPosition() { 1524 void IRRegExpMacroAssembler::PopCurrentPosition() {
1500 TAG(); 1525 TAG();
1501 StoreLocal(current_position_, PopStack()); 1526 StoreLocal(current_position_, PopStack());
1502 } 1527 }
1503 1528
1504 1529
1505 void IRRegExpMacroAssembler::PopRegister(intptr_t register_index) { 1530 void IRRegExpMacroAssembler::PopRegister(intptr_t reg) {
1506 TAG(); 1531 TAG();
1507 ASSERT(register_index < position_registers_.length()); 1532 ASSERT(reg < registers_count_);
1508 StoreLocal(position_register(register_index), PopStack()); 1533 PushArgumentInstr* registers_push = PushLocal(registers_);
1534 PushArgumentInstr* index_push = PushRegisterIndex(reg);
1535 PushArgumentInstr* pop_push = PushArgument(PopStack());
1536 StoreRegister(registers_push, index_push, pop_push);
1509 } 1537 }
1510 1538
1511 1539
1512 void IRRegExpMacroAssembler::PushStack(Definition *definition) { 1540 void IRRegExpMacroAssembler::PushStack(Definition *definition) {
1513 PushArgumentInstr* stack_push = PushLocal(stack_); 1541 PushArgumentInstr* stack_push = PushLocal(stack_);
1514 PushArgumentInstr* value_push = PushArgument(Bind(definition)); 1542 PushArgumentInstr* value_push = PushArgument(Bind(definition));
1515 Do(InstanceCall(InstanceCallDescriptor(Symbols::add()), 1543 Do(InstanceCall(InstanceCallDescriptor(Symbols::add()),
1516 stack_push, 1544 stack_push,
1517 value_push)); 1545 value_push));
1518 } 1546 }
(...skipping 22 matching lines...) Expand all
1541 PushStack(offset); 1569 PushStack(offset);
1542 } 1570 }
1543 1571
1544 1572
1545 void IRRegExpMacroAssembler::PushCurrentPosition() { 1573 void IRRegExpMacroAssembler::PushCurrentPosition() {
1546 TAG(); 1574 TAG();
1547 PushStack(LoadLocal(current_position_)); 1575 PushStack(LoadLocal(current_position_));
1548 } 1576 }
1549 1577
1550 1578
1551 void IRRegExpMacroAssembler::PushRegister(intptr_t register_index) { 1579 void IRRegExpMacroAssembler::PushRegister(intptr_t reg) {
1552 TAG(); 1580 TAG();
1553 PushStack(LoadLocal(position_register(register_index))); 1581 PushArgumentInstr* stack_push = PushLocal(stack_);
1582 PushArgumentInstr* value_push = PushArgument(LoadRegister(reg));
1583 Do(InstanceCall(InstanceCallDescriptor(Symbols::add()),
1584 stack_push,
1585 value_push));
1554 } 1586 }
1555 1587
1556 1588
1557 void IRRegExpMacroAssembler::ReadCurrentPositionFromRegister(intptr_t reg) { 1589 void IRRegExpMacroAssembler::ReadCurrentPositionFromRegister(intptr_t reg) {
1558 TAG(); 1590 TAG();
1559 StoreLocal(current_position_, Bind(LoadLocal(position_register(reg)))); 1591 StoreLocal(current_position_, LoadRegister(reg));
1560 } 1592 }
1561 1593
1562 // Resets the size of the stack to the value stored in reg. 1594 // Resets the size of the stack to the value stored in reg.
1563 void IRRegExpMacroAssembler::ReadStackPointerFromRegister(intptr_t reg) { 1595 void IRRegExpMacroAssembler::ReadStackPointerFromRegister(intptr_t reg) {
1564 TAG(); 1596 TAG();
1565 ASSERT(reg < position_registers_.length()); 1597 ASSERT(reg < registers_count_);
1566 1598
1567 PushArgumentInstr* stack_push = PushLocal(stack_); 1599 PushArgumentInstr* stack_push = PushLocal(stack_);
1568 PushArgumentInstr* length_push = PushLocal(position_register(reg)); 1600 PushArgumentInstr* length_push = PushArgument(LoadRegister(reg));
1569 1601
1570 Do(InstanceCall( 1602 Do(InstanceCall(
1571 InstanceCallDescriptor( 1603 InstanceCallDescriptor(
1572 String::ZoneHandle(I, Field::SetterSymbol(Symbols::Length()))), 1604 String::ZoneHandle(I, Field::SetterSymbol(Symbols::Length()))),
1573 stack_push, 1605 stack_push,
1574 length_push)); 1606 length_push));
1575 } 1607 }
1576 1608
1577 void IRRegExpMacroAssembler::SetCurrentPositionFromEnd(intptr_t by) { 1609 void IRRegExpMacroAssembler::SetCurrentPositionFromEnd(intptr_t by) {
1578 TAG(); 1610 TAG();
(...skipping 10 matching lines...) Expand all
1589 1621
1590 // On RegExp code entry (where this operation is used), the character before 1622 // On RegExp code entry (where this operation is used), the character before
1591 // the current position is expected to be already loaded. 1623 // the current position is expected to be already loaded.
1592 // We have advanced the position, so it's safe to read backwards. 1624 // We have advanced the position, so it's safe to read backwards.
1593 LoadCurrentCharacterUnchecked(-1, 1); 1625 LoadCurrentCharacterUnchecked(-1, 1);
1594 1626
1595 BindBlock(&after_position); 1627 BindBlock(&after_position);
1596 } 1628 }
1597 1629
1598 1630
1599 void IRRegExpMacroAssembler::SetRegister(intptr_t register_index, intptr_t to) { 1631 void IRRegExpMacroAssembler::SetRegister(intptr_t reg, intptr_t to) {
1600 TAG(); 1632 TAG();
1601 // Reserved for positions! 1633 // Reserved for positions!
1602 ASSERT(register_index >= position_registers_count_); 1634 ASSERT(reg >= saved_registers_count_);
1603 StoreLocal(position_register(register_index), Bind(Int64Constant(to))); 1635 StoreRegister(reg, to);
1604 } 1636 }
1605 1637
1606 1638
1607 bool IRRegExpMacroAssembler::Succeed() { 1639 bool IRRegExpMacroAssembler::Succeed() {
1608 TAG(); 1640 TAG();
1609 GoTo(success_block_); 1641 GoTo(success_block_);
1610 return global(); 1642 return global();
1611 } 1643 }
1612 1644
1613 1645
1614 void IRRegExpMacroAssembler::WriteCurrentPositionToRegister( 1646 void IRRegExpMacroAssembler::WriteCurrentPositionToRegister(
1615 intptr_t reg, intptr_t cp_offset) { 1647 intptr_t reg, intptr_t cp_offset) {
1616 TAG(); 1648 TAG();
1617 1649
1650 PushArgumentInstr* registers_push = PushLocal(registers_);
1651 PushArgumentInstr* index_push = PushRegisterIndex(reg);
1618 PushArgumentInstr* pos_push = PushLocal(current_position_); 1652 PushArgumentInstr* pos_push = PushLocal(current_position_);
1619 PushArgumentInstr* off_push = 1653 PushArgumentInstr* off_push = PushArgument(Bind(Int64Constant(cp_offset)));
1620 PushArgument(Bind(Int64Constant(cp_offset))); 1654 PushArgumentInstr* neg_off_push = PushArgument(Bind(Add(pos_push, off_push)));
1621
1622 // Push the negative offset; these are converted to positive string positions 1655 // Push the negative offset; these are converted to positive string positions
1623 // within the success block. 1656 // within the success block.
1624 StoreLocal(position_register(reg), Bind(Add(pos_push, off_push))); 1657 StoreRegister(registers_push, index_push, neg_off_push);
1625 } 1658 }
1626 1659
1627 1660
1628 void IRRegExpMacroAssembler::ClearRegisters( 1661 void IRRegExpMacroAssembler::ClearRegisters(
1629 intptr_t reg_from, intptr_t reg_to) { 1662 intptr_t reg_from, intptr_t reg_to) {
1630 TAG(); 1663 TAG();
1631 1664
1632 ASSERT(reg_from <= reg_to); 1665 ASSERT(reg_from <= reg_to);
1633 ASSERT(reg_to < position_registers_.length());
1634 1666
1635 // In order to clear registers to a final result value of -1, set them to 1667 // In order to clear registers to a final result value of -1, set them to
1636 // (-1 - string length), the offset of -1 from the end of the string. 1668 // (-1 - string length), the offset of -1 from the end of the string.
1637 1669
1638 for (intptr_t reg = reg_from; reg <= reg_to; reg++) { 1670 for (intptr_t reg = reg_from; reg <= reg_to; reg++) {
1671 PushArgumentInstr* registers_push = PushLocal(registers_);
1672 PushArgumentInstr* index_push = PushRegisterIndex(reg);
1639 PushArgumentInstr* minus_one_push = 1673 PushArgumentInstr* minus_one_push =
1640 PushArgument(Bind(Int64Constant(-1))); 1674 PushArgument(Bind(Int64Constant(-1)));
1641 PushArgumentInstr* length_push = PushLocal(string_param_length_); 1675 PushArgumentInstr* length_push = PushLocal(string_param_length_);
1642 1676 PushArgumentInstr* value_push =
1643 StoreLocal(position_register(reg), Bind(Sub(minus_one_push, length_push))); 1677 PushArgument(Bind(Sub(minus_one_push, length_push)));
1678 StoreRegister(registers_push, index_push, value_push);
1644 } 1679 }
1645 } 1680 }
1646 1681
1647 1682
1648 void IRRegExpMacroAssembler::WriteStackPointerToRegister(intptr_t reg) { 1683 void IRRegExpMacroAssembler::WriteStackPointerToRegister(intptr_t reg) {
1649 TAG(); 1684 TAG();
1650 1685
1686 PushArgumentInstr* registers_push = PushLocal(registers_);
1687 PushArgumentInstr* index_push = PushRegisterIndex(reg);
1651 PushArgumentInstr* stack_push = PushLocal(stack_); 1688 PushArgumentInstr* stack_push = PushLocal(stack_);
1652 Value* length_value = 1689 PushArgumentInstr* length_push =
1653 Bind(InstanceCall(InstanceCallDescriptor( 1690 PushArgument(Bind(InstanceCall(InstanceCallDescriptor(
1654 String::ZoneHandle( 1691 String::ZoneHandle(I, Field::GetterSymbol(Symbols::Length()))),
1655 I, Field::GetterSymbol(Symbols::Length()))), 1692 stack_push)));
1656 stack_push)); 1693 StoreRegister(registers_push, index_push, length_push);
1657
1658 StoreLocal(position_register(reg), length_value);
1659 } 1694 }
1660 1695
1661 1696
1662 // Private methods: 1697 // Private methods:
1663 1698
1664 1699
1665 void IRRegExpMacroAssembler::CheckPosition(intptr_t cp_offset, 1700 void IRRegExpMacroAssembler::CheckPosition(intptr_t cp_offset,
1666 BlockLabel* on_outside_input) { 1701 BlockLabel* on_outside_input) {
1667 TAG(); 1702 TAG();
1668 Definition* curpos_def = LoadLocal(current_position_); 1703 Definition* curpos_def = LoadLocal(current_position_);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1826 index_val, 1861 index_val,
1827 characters, 1862 characters,
1828 specialization_cid_, 1863 specialization_cid_,
1829 Scanner::kNoSourcePos)); 1864 Scanner::kNoSourcePos));
1830 } 1865 }
1831 1866
1832 1867
1833 #undef __ 1868 #undef __
1834 1869
1835 } // namespace dart 1870 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/regexp_assembler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698