| 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 |