OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/builtins/builtins-constructor.h" | 5 #include "src/builtins/builtins-constructor.h" |
6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
7 #include "src/builtins/builtins.h" | 7 #include "src/builtins/builtins.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stub-assembler.h" | 9 #include "src/code-stub-assembler.h" |
10 #include "src/regexp/jsregexp.h" | 10 #include "src/regexp/jsregexp.h" |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 Node* const result_elements = LoadElements(result); | 163 Node* const result_elements = LoadElements(result); |
164 | 164 |
165 StoreFixedArrayElement(result_elements, 0, first, SKIP_WRITE_BARRIER); | 165 StoreFixedArrayElement(result_elements, 0, first, SKIP_WRITE_BARRIER); |
166 | 166 |
167 GotoIf(SmiEqual(num_results, SmiConstant(Smi::FromInt(1))), &out); | 167 GotoIf(SmiEqual(num_results, SmiConstant(Smi::FromInt(1))), &out); |
168 | 168 |
169 // Store all remaining captures. | 169 // Store all remaining captures. |
170 Node* const limit = IntPtrAdd( | 170 Node* const limit = IntPtrAdd( |
171 IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex), num_indices); | 171 IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex), num_indices); |
172 | 172 |
173 Variable var_from_cursor(this, MachineType::PointerRepresentation()); | 173 Variable var_from_cursor( |
174 Variable var_to_cursor(this, MachineType::PointerRepresentation()); | 174 this, MachineType::PointerRepresentation(), |
175 | 175 IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 2)); |
176 var_from_cursor.Bind(IntPtrConstant(RegExpMatchInfo::kFirstCaptureIndex + 2)); | 176 Variable var_to_cursor(this, MachineType::PointerRepresentation(), |
177 var_to_cursor.Bind(IntPtrConstant(1)); | 177 IntPtrConstant(1)); |
178 | 178 |
179 Variable* vars[] = {&var_from_cursor, &var_to_cursor}; | 179 Variable* vars[] = {&var_from_cursor, &var_to_cursor}; |
180 Label loop(this, 2, vars); | 180 Label loop(this, 2, vars); |
181 | 181 |
182 Goto(&loop); | 182 Goto(&loop); |
183 Bind(&loop); | 183 Bind(&loop); |
184 { | 184 { |
185 Node* const from_cursor = var_from_cursor.value(); | 185 Node* const from_cursor = var_from_cursor.value(); |
186 Node* const to_cursor = var_to_cursor.value(); | 186 Node* const to_cursor = var_to_cursor.value(); |
187 Node* const start = LoadFixedArrayElement(match_info, from_cursor); | 187 Node* const start = LoadFixedArrayElement(match_info, from_cursor); |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 } | 485 } |
486 } | 486 } |
487 | 487 |
488 Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context, | 488 Node* RegExpBuiltinsAssembler::FlagsGetter(Node* const context, |
489 Node* const regexp, | 489 Node* const regexp, |
490 bool is_fastpath) { | 490 bool is_fastpath) { |
491 Isolate* isolate = this->isolate(); | 491 Isolate* isolate = this->isolate(); |
492 | 492 |
493 Node* const int_zero = IntPtrConstant(0); | 493 Node* const int_zero = IntPtrConstant(0); |
494 Node* const int_one = IntPtrConstant(1); | 494 Node* const int_one = IntPtrConstant(1); |
495 Variable var_length(this, MachineType::PointerRepresentation()); | 495 Variable var_length(this, MachineType::PointerRepresentation(), int_zero); |
496 Variable var_flags(this, MachineType::PointerRepresentation()); | 496 Variable var_flags(this, MachineType::PointerRepresentation()); |
497 | 497 |
498 // First, count the number of characters we will need and check which flags | 498 // First, count the number of characters we will need and check which flags |
499 // are set. | 499 // are set. |
500 | 500 |
501 var_length.Bind(int_zero); | |
502 | |
503 if (is_fastpath) { | 501 if (is_fastpath) { |
504 // Refer to JSRegExp's flag property on the fast-path. | 502 // Refer to JSRegExp's flag property on the fast-path. |
505 Node* const flags_smi = LoadObjectField(regexp, JSRegExp::kFlagsOffset); | 503 Node* const flags_smi = LoadObjectField(regexp, JSRegExp::kFlagsOffset); |
506 Node* const flags_intptr = SmiUntag(flags_smi); | 504 Node* const flags_intptr = SmiUntag(flags_smi); |
507 var_flags.Bind(flags_intptr); | 505 var_flags.Bind(flags_intptr); |
508 | 506 |
509 #define CASE_FOR_FLAG(FLAG) \ | 507 #define CASE_FOR_FLAG(FLAG) \ |
510 do { \ | 508 do { \ |
511 Label next(this); \ | 509 Label next(this); \ |
512 GotoUnless(IsSetWord(flags_intptr, FLAG), &next); \ | 510 GotoUnless(IsSetWord(flags_intptr, FLAG), &next); \ |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 #undef CASE_FOR_FLAG | 550 #undef CASE_FOR_FLAG |
553 } | 551 } |
554 | 552 |
555 // Allocate a string of the required length and fill it with the corresponding | 553 // Allocate a string of the required length and fill it with the corresponding |
556 // char for each set flag. | 554 // char for each set flag. |
557 | 555 |
558 { | 556 { |
559 Node* const result = AllocateSeqOneByteString(context, var_length.value()); | 557 Node* const result = AllocateSeqOneByteString(context, var_length.value()); |
560 Node* const flags_intptr = var_flags.value(); | 558 Node* const flags_intptr = var_flags.value(); |
561 | 559 |
562 Variable var_offset(this, MachineType::PointerRepresentation()); | 560 Variable var_offset( |
563 var_offset.Bind( | 561 this, MachineType::PointerRepresentation(), |
564 IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag)); | 562 IntPtrConstant(SeqOneByteString::kHeaderSize - kHeapObjectTag)); |
565 | 563 |
566 #define CASE_FOR_FLAG(FLAG, CHAR) \ | 564 #define CASE_FOR_FLAG(FLAG, CHAR) \ |
567 do { \ | 565 do { \ |
568 Label next(this); \ | 566 Label next(this); \ |
569 GotoUnless(IsSetWord(flags_intptr, FLAG), &next); \ | 567 GotoUnless(IsSetWord(flags_intptr, FLAG), &next); \ |
570 Node* const value = Int32Constant(CHAR); \ | 568 Node* const value = Int32Constant(CHAR); \ |
571 StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \ | 569 StoreNoWriteBarrier(MachineRepresentation::kWord8, result, \ |
572 var_offset.value(), value); \ | 570 var_offset.value(), value); \ |
573 var_offset.Bind(IntPtrAdd(var_offset.value(), int_one)); \ | 571 var_offset.Bind(IntPtrAdd(var_offset.value(), int_one)); \ |
(...skipping 10 matching lines...) Expand all Loading... |
584 | 582 |
585 return result; | 583 return result; |
586 } | 584 } |
587 } | 585 } |
588 | 586 |
589 // ES#sec-isregexp IsRegExp ( argument ) | 587 // ES#sec-isregexp IsRegExp ( argument ) |
590 Node* RegExpBuiltinsAssembler::IsRegExp(Node* const context, | 588 Node* RegExpBuiltinsAssembler::IsRegExp(Node* const context, |
591 Node* const maybe_receiver) { | 589 Node* const maybe_receiver) { |
592 Label out(this), if_isregexp(this); | 590 Label out(this), if_isregexp(this); |
593 | 591 |
594 Variable var_result(this, MachineRepresentation::kWord32); | 592 Variable var_result(this, MachineRepresentation::kWord32, Int32Constant(0)); |
595 var_result.Bind(Int32Constant(0)); | |
596 | 593 |
597 GotoIf(TaggedIsSmi(maybe_receiver), &out); | 594 GotoIf(TaggedIsSmi(maybe_receiver), &out); |
598 GotoUnless(IsJSReceiver(maybe_receiver), &out); | 595 GotoUnless(IsJSReceiver(maybe_receiver), &out); |
599 | 596 |
600 Node* const receiver = maybe_receiver; | 597 Node* const receiver = maybe_receiver; |
601 | 598 |
602 // Check @@match. | 599 // Check @@match. |
603 { | 600 { |
604 Callable getproperty_callable = CodeFactory::GetProperty(isolate()); | 601 Callable getproperty_callable = CodeFactory::GetProperty(isolate()); |
605 Node* const name = HeapConstant(isolate()->factory()->match_symbol()); | 602 Node* const name = HeapConstant(isolate()->factory()->match_symbol()); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 // ES#sec-regexp-pattern-flags | 666 // ES#sec-regexp-pattern-flags |
670 // RegExp ( pattern, flags ) | 667 // RegExp ( pattern, flags ) |
671 TF_BUILTIN(RegExpConstructor, RegExpBuiltinsAssembler) { | 668 TF_BUILTIN(RegExpConstructor, RegExpBuiltinsAssembler) { |
672 Node* const pattern = Parameter(1); | 669 Node* const pattern = Parameter(1); |
673 Node* const flags = Parameter(2); | 670 Node* const flags = Parameter(2); |
674 Node* const new_target = Parameter(3); | 671 Node* const new_target = Parameter(3); |
675 Node* const context = Parameter(5); | 672 Node* const context = Parameter(5); |
676 | 673 |
677 Isolate* isolate = this->isolate(); | 674 Isolate* isolate = this->isolate(); |
678 | 675 |
679 Variable var_flags(this, MachineRepresentation::kTagged); | 676 Variable var_flags(this, MachineRepresentation::kTagged, flags); |
680 Variable var_pattern(this, MachineRepresentation::kTagged); | 677 Variable var_pattern(this, MachineRepresentation::kTagged, pattern); |
681 Variable var_new_target(this, MachineRepresentation::kTagged); | 678 Variable var_new_target(this, MachineRepresentation::kTagged, new_target); |
682 | |
683 var_flags.Bind(flags); | |
684 var_pattern.Bind(pattern); | |
685 var_new_target.Bind(new_target); | |
686 | 679 |
687 Node* const native_context = LoadNativeContext(context); | 680 Node* const native_context = LoadNativeContext(context); |
688 Node* const regexp_function = | 681 Node* const regexp_function = |
689 LoadContextElement(native_context, Context::REGEXP_FUNCTION_INDEX); | 682 LoadContextElement(native_context, Context::REGEXP_FUNCTION_INDEX); |
690 | 683 |
691 Node* const pattern_is_regexp = IsRegExp(context, pattern); | 684 Node* const pattern_is_regexp = IsRegExp(context, pattern); |
692 | 685 |
693 { | 686 { |
694 Label next(this); | 687 Label next(this); |
695 | 688 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
807 TF_BUILTIN(RegExpPrototypeCompile, RegExpBuiltinsAssembler) { | 800 TF_BUILTIN(RegExpPrototypeCompile, RegExpBuiltinsAssembler) { |
808 Node* const maybe_receiver = Parameter(0); | 801 Node* const maybe_receiver = Parameter(0); |
809 Node* const maybe_pattern = Parameter(1); | 802 Node* const maybe_pattern = Parameter(1); |
810 Node* const maybe_flags = Parameter(2); | 803 Node* const maybe_flags = Parameter(2); |
811 Node* const context = Parameter(5); | 804 Node* const context = Parameter(5); |
812 | 805 |
813 ThrowIfNotInstanceType(context, maybe_receiver, JS_REGEXP_TYPE, | 806 ThrowIfNotInstanceType(context, maybe_receiver, JS_REGEXP_TYPE, |
814 "RegExp.prototype.compile"); | 807 "RegExp.prototype.compile"); |
815 Node* const receiver = maybe_receiver; | 808 Node* const receiver = maybe_receiver; |
816 | 809 |
817 Variable var_flags(this, MachineRepresentation::kTagged); | 810 Variable var_flags(this, MachineRepresentation::kTagged, maybe_flags); |
818 Variable var_pattern(this, MachineRepresentation::kTagged); | 811 Variable var_pattern(this, MachineRepresentation::kTagged, maybe_pattern); |
819 | |
820 var_flags.Bind(maybe_flags); | |
821 var_pattern.Bind(maybe_pattern); | |
822 | 812 |
823 // Handle a JSRegExp pattern. | 813 // Handle a JSRegExp pattern. |
824 { | 814 { |
825 Label next(this); | 815 Label next(this); |
826 | 816 |
827 GotoIf(TaggedIsSmi(maybe_pattern), &next); | 817 GotoIf(TaggedIsSmi(maybe_pattern), &next); |
828 GotoUnless(HasInstanceType(maybe_pattern, JS_REGEXP_TYPE), &next); | 818 GotoUnless(HasInstanceType(maybe_pattern, JS_REGEXP_TYPE), &next); |
829 | 819 |
830 Node* const pattern = maybe_pattern; | 820 Node* const pattern = maybe_pattern; |
831 | 821 |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1299 // Return true iff exec matched successfully. | 1289 // Return true iff exec matched successfully. |
1300 Node* const result = | 1290 Node* const result = |
1301 SelectBooleanConstant(WordNotEqual(match_indices, NullConstant())); | 1291 SelectBooleanConstant(WordNotEqual(match_indices, NullConstant())); |
1302 Return(result); | 1292 Return(result); |
1303 } | 1293 } |
1304 } | 1294 } |
1305 | 1295 |
1306 Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string, | 1296 Node* RegExpBuiltinsAssembler::AdvanceStringIndex(Node* const string, |
1307 Node* const index, | 1297 Node* const index, |
1308 Node* const is_unicode) { | 1298 Node* const is_unicode) { |
1309 Variable var_result(this, MachineRepresentation::kTagged); | |
1310 | |
1311 // Default to last_index + 1. | 1299 // Default to last_index + 1. |
1312 Node* const index_plus_one = SmiAdd(index, SmiConstant(1)); | 1300 Node* const index_plus_one = SmiAdd(index, SmiConstant(1)); |
1313 var_result.Bind(index_plus_one); | 1301 Variable var_result(this, MachineRepresentation::kTagged, index_plus_one); |
1314 | 1302 |
1315 Label if_isunicode(this), out(this); | 1303 Label if_isunicode(this), out(this); |
1316 Branch(is_unicode, &if_isunicode, &out); | 1304 Branch(is_unicode, &if_isunicode, &out); |
1317 | 1305 |
1318 Bind(&if_isunicode); | 1306 Bind(&if_isunicode); |
1319 { | 1307 { |
1320 Node* const string_length = LoadStringLength(string); | 1308 Node* const string_length = LoadStringLength(string); |
1321 GotoUnless(SmiLessThan(index_plus_one, string_length), &out); | 1309 GotoUnless(SmiLessThan(index_plus_one, string_length), &out); |
1322 | 1310 |
1323 Node* const lead = StringCharCodeAt(string, index); | 1311 Node* const lead = StringCharCodeAt(string, index); |
(...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2522 Bind(&if_matched); | 2510 Bind(&if_matched); |
2523 { | 2511 { |
2524 Node* result = | 2512 Node* result = |
2525 ConstructNewResultFromMatchInfo(context, match_indices, string); | 2513 ConstructNewResultFromMatchInfo(context, match_indices, string); |
2526 Return(result); | 2514 Return(result); |
2527 } | 2515 } |
2528 } | 2516 } |
2529 | 2517 |
2530 } // namespace internal | 2518 } // namespace internal |
2531 } // namespace v8 | 2519 } // namespace v8 |
OLD | NEW |