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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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
« no previous file with comments | « runtime/vm/regexp_assembler_bytecode.h ('k') | runtime/vm/regexp_assembler_bytecode_inl.h » ('j') | 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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/regexp_assembler_bytecode.h" 5 #include "vm/regexp_assembler_bytecode.h"
6 6
7 #include "vm/regexp_assembler_bytecode_inl.h" 7 #include "vm/regexp_assembler_bytecode_inl.h"
8 #include "vm/exceptions.h" 8 #include "vm/exceptions.h"
9 #include "vm/object_store.h" 9 #include "vm/object_store.h"
10 #include "vm/regexp_bytecodes.h" 10 #include "vm/regexp_bytecodes.h"
11 #include "vm/regexp_assembler.h" 11 #include "vm/regexp_assembler.h"
12 #include "vm/regexp.h" 12 #include "vm/regexp.h"
13 #include "vm/regexp_parser.h" 13 #include "vm/regexp_parser.h"
14 #include "vm/regexp_interpreter.h" 14 #include "vm/regexp_interpreter.h"
15 #include "vm/timeline.h" 15 #include "vm/timeline.h"
16 16
17 namespace dart { 17 namespace dart {
18 18
19 BytecodeRegExpMacroAssembler::BytecodeRegExpMacroAssembler( 19 BytecodeRegExpMacroAssembler::BytecodeRegExpMacroAssembler(
20 ZoneGrowableArray<uint8_t>* buffer, 20 ZoneGrowableArray<uint8_t>* buffer,
21 Zone* zone) 21 Zone* zone)
22 : RegExpMacroAssembler(zone), 22 : RegExpMacroAssembler(zone),
23 buffer_(buffer), 23 buffer_(buffer),
24 pc_(0), 24 pc_(0),
25 advance_current_end_(kInvalidPC) { } 25 advance_current_end_(kInvalidPC) {}
26 26
27 27
28 BytecodeRegExpMacroAssembler::~BytecodeRegExpMacroAssembler() { 28 BytecodeRegExpMacroAssembler::~BytecodeRegExpMacroAssembler() {
29 if (backtrack_.is_linked()) backtrack_.Unuse(); 29 if (backtrack_.is_linked()) backtrack_.Unuse();
30 } 30 }
31 31
32 32
33 BytecodeRegExpMacroAssembler::IrregexpImplementation 33 BytecodeRegExpMacroAssembler::IrregexpImplementation
34 BytecodeRegExpMacroAssembler::Implementation() { 34 BytecodeRegExpMacroAssembler::Implementation() {
35 return kBytecodeImplementation; 35 return kBytecodeImplementation;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 74
75 75
76 void BytecodeRegExpMacroAssembler::PushRegister(intptr_t register_index) { 76 void BytecodeRegExpMacroAssembler::PushRegister(intptr_t register_index) {
77 ASSERT(register_index >= 0); 77 ASSERT(register_index >= 0);
78 ASSERT(register_index <= kMaxRegister); 78 ASSERT(register_index <= kMaxRegister);
79 Emit(BC_PUSH_REGISTER, register_index); 79 Emit(BC_PUSH_REGISTER, register_index);
80 } 80 }
81 81
82 82
83 void BytecodeRegExpMacroAssembler::WriteCurrentPositionToRegister( 83 void BytecodeRegExpMacroAssembler::WriteCurrentPositionToRegister(
84 intptr_t register_index, intptr_t cp_offset) { 84 intptr_t register_index,
85 intptr_t cp_offset) {
85 ASSERT(register_index >= 0); 86 ASSERT(register_index >= 0);
86 ASSERT(register_index <= kMaxRegister); 87 ASSERT(register_index <= kMaxRegister);
87 Emit(BC_SET_REGISTER_TO_CP, register_index); 88 Emit(BC_SET_REGISTER_TO_CP, register_index);
88 Emit32(cp_offset); // Current position offset. 89 Emit32(cp_offset); // Current position offset.
89 } 90 }
90 91
91 92
92 void BytecodeRegExpMacroAssembler::ClearRegisters(intptr_t reg_from, 93 void BytecodeRegExpMacroAssembler::ClearRegisters(intptr_t reg_from,
93 intptr_t reg_to) { 94 intptr_t reg_to) {
94 ASSERT(reg_from <= reg_to); 95 ASSERT(reg_from <= reg_to);
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 ASSERT(by >= kMinCPOffset); 198 ASSERT(by >= kMinCPOffset);
198 ASSERT(by <= kMaxCPOffset); 199 ASSERT(by <= kMaxCPOffset);
199 advance_current_start_ = pc_; 200 advance_current_start_ = pc_;
200 advance_current_offset_ = by; 201 advance_current_offset_ = by;
201 Emit(BC_ADVANCE_CP, by); 202 Emit(BC_ADVANCE_CP, by);
202 advance_current_end_ = pc_; 203 advance_current_end_ = pc_;
203 } 204 }
204 205
205 206
206 void BytecodeRegExpMacroAssembler::CheckGreedyLoop( 207 void BytecodeRegExpMacroAssembler::CheckGreedyLoop(
207 BlockLabel* on_tos_equals_current_position) { 208 BlockLabel* on_tos_equals_current_position) {
208 Emit(BC_CHECK_GREEDY, 0); 209 Emit(BC_CHECK_GREEDY, 0);
209 EmitOrLink(on_tos_equals_current_position); 210 EmitOrLink(on_tos_equals_current_position);
210 } 211 }
211 212
212 213
213 void BytecodeRegExpMacroAssembler::LoadCurrentCharacter(intptr_t cp_offset, 214 void BytecodeRegExpMacroAssembler::LoadCurrentCharacter(intptr_t cp_offset,
214 BlockLabel* on_failure, 215 BlockLabel* on_failure,
215 bool check_bounds, 216 bool check_bounds,
216 intptr_t characters) { 217 intptr_t characters) {
217 ASSERT(cp_offset >= kMinCPOffset); 218 ASSERT(cp_offset >= kMinCPOffset);
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 uint16_t from, 350 uint16_t from,
350 uint16_t to, 351 uint16_t to,
351 BlockLabel* on_not_in_range) { 352 BlockLabel* on_not_in_range) {
352 Emit(BC_CHECK_CHAR_NOT_IN_RANGE, 0); 353 Emit(BC_CHECK_CHAR_NOT_IN_RANGE, 0);
353 Emit16(from); 354 Emit16(from);
354 Emit16(to); 355 Emit16(to);
355 EmitOrLink(on_not_in_range); 356 EmitOrLink(on_not_in_range);
356 } 357 }
357 358
358 359
359 void BytecodeRegExpMacroAssembler::CheckBitInTable( 360 void BytecodeRegExpMacroAssembler::CheckBitInTable(const TypedData& table,
360 const TypedData& table, BlockLabel* on_bit_set) { 361 BlockLabel* on_bit_set) {
361 Emit(BC_CHECK_BIT_IN_TABLE, 0); 362 Emit(BC_CHECK_BIT_IN_TABLE, 0);
362 EmitOrLink(on_bit_set); 363 EmitOrLink(on_bit_set);
363 for (int i = 0; i < kTableSize; i += kBitsPerByte) { 364 for (int i = 0; i < kTableSize; i += kBitsPerByte) {
364 int byte = 0; 365 int byte = 0;
365 for (int j = 0; j < kBitsPerByte; j++) { 366 for (int j = 0; j < kBitsPerByte; j++) {
366 if (table.GetUint8(i + j) != 0) byte |= 1 << j; 367 if (table.GetUint8(i + j) != 0) byte |= 1 << j;
367 } 368 }
368 Emit8(byte); 369 Emit8(byte);
369 } 370 }
370 } 371 }
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
442 } 443 }
443 444
444 445
445 void BytecodeRegExpMacroAssembler::Expand() { 446 void BytecodeRegExpMacroAssembler::Expand() {
446 // BOGUS 447 // BOGUS
447 buffer_->Add(0); 448 buffer_->Add(0);
448 buffer_->Add(0); 449 buffer_->Add(0);
449 buffer_->Add(0); 450 buffer_->Add(0);
450 buffer_->Add(0); 451 buffer_->Add(0);
451 intptr_t x = buffer_->length(); 452 intptr_t x = buffer_->length();
452 for (intptr_t i = 0; i < x; i++) buffer_->Add(0); 453 for (intptr_t i = 0; i < x; i++)
454 buffer_->Add(0);
453 } 455 }
454 456
455 457
456 static intptr_t Prepare(const RegExp& regexp, 458 static intptr_t Prepare(const RegExp& regexp,
457 const String& subject, 459 const String& subject,
458 Zone* zone) { 460 Zone* zone) {
459 bool is_one_byte = subject.IsOneByteString() || 461 bool is_one_byte =
460 subject.IsExternalOneByteString(); 462 subject.IsOneByteString() || subject.IsExternalOneByteString();
461 463
462 if (regexp.bytecode(is_one_byte) == TypedData::null()) { 464 if (regexp.bytecode(is_one_byte) == TypedData::null()) {
463 const String& pattern = String::Handle(zone, regexp.pattern()); 465 const String& pattern = String::Handle(zone, regexp.pattern());
464 NOT_IN_PRODUCT(TimelineDurationScope tds(Thread::Current(), 466 #if !defined(PRODUCT)
465 Timeline::GetCompilerStream(), 467 TimelineDurationScope tds(Thread::Current(), Timeline::GetCompilerStream(),
466 "CompileIrregexpBytecode"); 468 "CompileIrregexpBytecode");
467 if (tds.enabled()) { 469 if (tds.enabled()) {
468 tds.SetNumArguments(1); 470 tds.SetNumArguments(1);
469 tds.CopyArgument(0, "pattern", pattern.ToCString()); 471 tds.CopyArgument(0, "pattern", pattern.ToCString());
470 }); // !PRODUCT 472 }
473 #endif // !defined(PRODUCT)
471 474
472 const bool multiline = regexp.is_multi_line(); 475 const bool multiline = regexp.is_multi_line();
473 RegExpCompileData* compile_data = new(zone) RegExpCompileData(); 476 RegExpCompileData* compile_data = new (zone) RegExpCompileData();
474 if (!RegExpParser::ParseRegExp(pattern, multiline, compile_data)) { 477 if (!RegExpParser::ParseRegExp(pattern, multiline, compile_data)) {
475 // Parsing failures are handled in the RegExp factory constructor. 478 // Parsing failures are handled in the RegExp factory constructor.
476 UNREACHABLE(); 479 UNREACHABLE();
477 } 480 }
478 481
479 regexp.set_num_bracket_expressions(compile_data->capture_count); 482 regexp.set_num_bracket_expressions(compile_data->capture_count);
480 if (compile_data->simple) { 483 if (compile_data->simple) {
481 regexp.set_is_simple(); 484 regexp.set_is_simple();
482 } else { 485 } else {
483 regexp.set_is_complex(); 486 regexp.set_is_complex();
(...skipping 14 matching lines...) Expand all
498 (Smi::Value(regexp.num_bracket_expressions()) + 1) * 2; 501 (Smi::Value(regexp.num_bracket_expressions()) + 1) * 2;
499 } 502 }
500 503
501 504
502 static IrregexpInterpreter::IrregexpResult ExecRaw(const RegExp& regexp, 505 static IrregexpInterpreter::IrregexpResult ExecRaw(const RegExp& regexp,
503 const String& subject, 506 const String& subject,
504 intptr_t index, 507 intptr_t index,
505 int32_t* output, 508 int32_t* output,
506 intptr_t output_size, 509 intptr_t output_size,
507 Zone* zone) { 510 Zone* zone) {
508 bool is_one_byte = subject.IsOneByteString() || 511 bool is_one_byte =
509 subject.IsExternalOneByteString(); 512 subject.IsOneByteString() || subject.IsExternalOneByteString();
510 513
511 ASSERT(regexp.num_bracket_expressions() != Smi::null()); 514 ASSERT(regexp.num_bracket_expressions() != Smi::null());
512 515
513 // We must have done EnsureCompiledIrregexp, so we can get the number of 516 // We must have done EnsureCompiledIrregexp, so we can get the number of
514 // registers. 517 // registers.
515 int number_of_capture_registers = 518 int number_of_capture_registers =
516 (Smi::Value(regexp.num_bracket_expressions()) + 1) * 2; 519 (Smi::Value(regexp.num_bracket_expressions()) + 1) * 2;
517 int32_t* raw_output = &output[number_of_capture_registers]; 520 int32_t* raw_output = &output[number_of_capture_registers];
518 521
519 // We do not touch the actual capture result registers until we know there 522 // We do not touch the actual capture result registers until we know there
520 // has been a match so that we can use those capture results to set the 523 // has been a match so that we can use those capture results to set the
521 // last match info. 524 // last match info.
522 for (int i = number_of_capture_registers - 1; i >= 0; i--) { 525 for (int i = number_of_capture_registers - 1; i >= 0; i--) {
523 raw_output[i] = -1; 526 raw_output[i] = -1;
524 } 527 }
525 528
526 const TypedData& bytecode = 529 const TypedData& bytecode =
(...skipping 24 matching lines...) Expand all
551 Zone* zone) { 554 Zone* zone) {
552 intptr_t required_registers = Prepare(regexp, subject, zone); 555 intptr_t required_registers = Prepare(regexp, subject, zone);
553 if (required_registers < 0) { 556 if (required_registers < 0) {
554 // Compiling failed with an exception. 557 // Compiling failed with an exception.
555 UNREACHABLE(); 558 UNREACHABLE();
556 } 559 }
557 560
558 // V8 uses a shared copy on the isolate when smaller than some threshold. 561 // V8 uses a shared copy on the isolate when smaller than some threshold.
559 int32_t* output_registers = zone->Alloc<int32_t>(required_registers); 562 int32_t* output_registers = zone->Alloc<int32_t>(required_registers);
560 563
561 IrregexpInterpreter::IrregexpResult result = ExecRaw(regexp, 564 IrregexpInterpreter::IrregexpResult result =
562 subject, 565 ExecRaw(regexp, subject, start_index.Value(), output_registers,
563 start_index.Value(), 566 required_registers, zone);
564 output_registers,
565 required_registers,
566 zone);
567 567
568 if (result == IrregexpInterpreter::RE_SUCCESS) { 568 if (result == IrregexpInterpreter::RE_SUCCESS) {
569 intptr_t capture_count = Smi::Value(regexp.num_bracket_expressions()); 569 intptr_t capture_count = Smi::Value(regexp.num_bracket_expressions());
570 intptr_t capture_register_count = (capture_count + 1) * 2; 570 intptr_t capture_register_count = (capture_count + 1) * 2;
571 ASSERT(required_registers >= capture_register_count); 571 ASSERT(required_registers >= capture_register_count);
572 572
573 const TypedData& result = 573 const TypedData& result = TypedData::Handle(
574 TypedData::Handle(TypedData::New(kTypedDataInt32ArrayCid, 574 TypedData::New(kTypedDataInt32ArrayCid, capture_register_count));
575 capture_register_count));
576 { 575 {
577 #ifdef DEBUG 576 #ifdef DEBUG
578 // These indices will be used with substring operations that don't check 577 // These indices will be used with substring operations that don't check
579 // bounds, so sanity check them here. 578 // bounds, so sanity check them here.
580 for (intptr_t i = 0; i < capture_register_count; i++) { 579 for (intptr_t i = 0; i < capture_register_count; i++) {
581 int32_t val = output_registers[i]; 580 int32_t val = output_registers[i];
582 ASSERT(val == -1 || (val >= 0 && val <= subject.Length())); 581 ASSERT(val == -1 || (val >= 0 && val <= subject.Length()));
583 } 582 }
584 #endif 583 #endif
585 584
586 NoSafepointScope no_safepoint; 585 NoSafepointScope no_safepoint;
587 memmove(result.DataAddr(0), 586 memmove(result.DataAddr(0), output_registers,
588 output_registers,
589 capture_register_count * sizeof(int32_t)); 587 capture_register_count * sizeof(int32_t));
590 } 588 }
591 589
592 return result.raw(); 590 return result.raw();
593 } 591 }
594 if (result == IrregexpInterpreter::RE_EXCEPTION) { 592 if (result == IrregexpInterpreter::RE_EXCEPTION) {
595 UNREACHABLE(); 593 UNREACHABLE();
596 } 594 }
597 ASSERT(result == IrregexpInterpreter::RE_FAILURE); 595 ASSERT(result == IrregexpInterpreter::RE_FAILURE);
598 return Instance::null(); 596 return Instance::null();
599 } 597 }
600 598
601 599
602 } // namespace dart 600 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/regexp_assembler_bytecode.h ('k') | runtime/vm/regexp_assembler_bytecode_inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698