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

Side by Side Diff: src/jsregexp.cc

Issue 11228: * No failures on our own tests.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/regexp2000/
Patch Set: Created 12 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 value->set(kJscreNumberOfCapturesIndex, Smi::FromInt(number_of_captures)); 453 value->set(kJscreNumberOfCapturesIndex, Smi::FromInt(number_of_captures));
454 value->set(kJscreInternalIndex, *internal); 454 value->set(kJscreInternalIndex, *internal);
455 Factory::SetRegExpData(re, JSRegExp::JSCRE, pattern, flags, value); 455 Factory::SetRegExpData(re, JSRegExp::JSCRE, pattern, flags, value);
456 456
457 return re; 457 return re;
458 } 458 }
459 459
460 460
461 Handle<Object> RegExpImpl::Re2kExecOnce(Handle<JSRegExp> regexp, 461 Handle<Object> RegExpImpl::Re2kExecOnce(Handle<JSRegExp> regexp,
462 int num_captures, 462 int num_captures,
463 Handle<String> subject, 463 Handle<String> two_byte_subject,
464 int previous_index, 464 int previous_index,
465 const uc16* two_byte_subject,
466 int* offsets_vector, 465 int* offsets_vector,
467 int offsets_vector_length) { 466 int offsets_vector_length) {
467 #ifdef DEBUG
468 if (FLAG_trace_regexp_bytecodes) {
469 String* pattern = regexp->Pattern();
470 PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString()));
471 PrintF("\n\nSubject string: '%s'\n\n", *(two_byte_subject->ToCString()));
472 }
473 #endif
474 ASSERT(StringShape(*two_byte_subject).IsTwoByteRepresentation());
475 ASSERT(two_byte_subject->IsFlat(StringShape(*two_byte_subject)));
468 bool rc; 476 bool rc;
469 { 477 {
470 for (int i = (num_captures + 1) * 2 - 1; i >= 0; i--) { 478 for (int i = (num_captures + 1) * 2 - 1; i >= 0; i--) {
471 offsets_vector[i] = -1; 479 offsets_vector[i] = -1;
472 } 480 }
473 481
474 AssertNoAllocation a; 482 LOG(RegExpExecEvent(regexp, previous_index, two_byte_subject));
475
476 LOG(RegExpExecEvent(regexp, previous_index, subject));
477 483
478 Handle<ByteArray> byte_codes = Re2kCode(regexp); 484 Handle<ByteArray> byte_codes = Re2kCode(regexp);
479 485
480 rc = Re2kInterpreter::Match(byte_codes, 486 rc = Re2kInterpreter::Match(byte_codes,
481 subject, 487 two_byte_subject,
482 offsets_vector, 488 offsets_vector,
483 previous_index); 489 previous_index);
484 } 490 }
485 491
486 if (!rc) { 492 if (!rc) {
487 return Factory::null_value(); 493 return Factory::null_value();
488 } 494 }
489 495
490 Handle<FixedArray> array = Factory::NewFixedArray(2 * (num_captures+1)); 496 Handle<FixedArray> array = Factory::NewFixedArray(2 * (num_captures+1));
491 // The captures come in (start, end+1) pairs. 497 // The captures come in (start, end+1) pairs.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 // Prepare space for the return values. 604 // Prepare space for the return values.
599 int number_of_registers = Re2kNumberOfRegisters(regexp); 605 int number_of_registers = Re2kNumberOfRegisters(regexp);
600 OffsetsVector offsets(number_of_registers); 606 OffsetsVector offsets(number_of_registers);
601 607
602 int num_captures = Re2kNumberOfCaptures(regexp); 608 int num_captures = Re2kNumberOfCaptures(regexp);
603 609
604 int previous_index = static_cast<int>(DoubleToInteger(index->Number())); 610 int previous_index = static_cast<int>(DoubleToInteger(index->Number()));
605 611
606 Handle<String> subject16 = CachedStringToTwoByte(subject); 612 Handle<String> subject16 = CachedStringToTwoByte(subject);
607 613
608 Handle<Object> result(Re2kExecOnce(regexp, 614 Handle<Object> result(
609 num_captures, 615 Re2kExecOnce(regexp,
610 subject, 616 num_captures,
611 previous_index, 617 subject16,
612 subject16->GetTwoByteData(), 618 previous_index,
613 offsets.vector(), 619 offsets.vector(),
614 offsets.length())); 620 offsets.length()));
615 return result; 621 return result;
616 } 622 }
617 623
618 624
619 Handle<Object> RegExpImpl::JscreExec(Handle<JSRegExp> regexp, 625 Handle<Object> RegExpImpl::JscreExec(Handle<JSRegExp> regexp,
620 Handle<String> subject, 626 Handle<String> subject,
621 Handle<Object> index) { 627 Handle<Object> index) {
622 ASSERT_EQ(regexp->TypeTag(), JSRegExp::JSCRE); 628 ASSERT_EQ(regexp->TypeTag(), JSRegExp::JSCRE);
623 if (regexp->DataAt(JSRegExp::kJscreDataIndex)->IsUndefined()) { 629 if (regexp->DataAt(JSRegExp::kJscreDataIndex)->IsUndefined()) {
624 Handle<Object> compile_result = JscreCompile(regexp); 630 Handle<Object> compile_result = JscreCompile(regexp);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 Handle<String> subject16 = CachedStringToTwoByte(subject); 670 Handle<String> subject16 = CachedStringToTwoByte(subject);
665 671
666 do { 672 do {
667 if (previous_index > subject->length() || previous_index < 0) { 673 if (previous_index > subject->length() || previous_index < 0) {
668 // Per ECMA-262 15.10.6.2, if the previous index is greater than the 674 // Per ECMA-262 15.10.6.2, if the previous index is greater than the
669 // string length, there is no match. 675 // string length, there is no match.
670 matches = Factory::null_value(); 676 matches = Factory::null_value();
671 } else { 677 } else {
672 matches = Re2kExecOnce(regexp, 678 matches = Re2kExecOnce(regexp,
673 Re2kNumberOfCaptures(regexp), 679 Re2kNumberOfCaptures(regexp),
674 subject, 680 subject16,
675 previous_index, 681 previous_index,
676 subject16->GetTwoByteData(),
677 offsets.vector(), 682 offsets.vector(),
678 offsets.length()); 683 offsets.length());
679 684
680 if (matches->IsJSArray()) { 685 if (matches->IsJSArray()) {
681 SetElement(result, i, matches); 686 SetElement(result, i, matches);
682 i++; 687 i++;
683 previous_index = offsets.vector()[1]; 688 previous_index = offsets.vector()[1];
684 if (offsets.vector()[0] == offsets.vector()[1]) { 689 if (offsets.vector()[0] == offsets.vector()[1]) {
685 previous_index++; 690 previous_index++;
686 } 691 }
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 inline void AddWork(RegExpNode* node) { work_list_->Add(node); } 843 inline void AddWork(RegExpNode* node) { work_list_->Add(node); }
839 844
840 static const int kImplementationOffset = 0; 845 static const int kImplementationOffset = 0;
841 static const int kNumberOfRegistersOffset = 0; 846 static const int kNumberOfRegistersOffset = 0;
842 static const int kCodeOffset = 1; 847 static const int kCodeOffset = 1;
843 848
844 RegExpMacroAssembler* macro_assembler() { return macro_assembler_; } 849 RegExpMacroAssembler* macro_assembler() { return macro_assembler_; }
845 EndNode* accept() { return accept_; } 850 EndNode* accept() { return accept_; }
846 EndNode* backtrack() { return backtrack_; } 851 EndNode* backtrack() { return backtrack_; }
847 852
853 static const int kMaxRecursion = 100;
854 inline int recursion_depth() { return recursion_depth_; }
855 inline void IncrementRecursionDepth() { recursion_depth_++; }
856 inline void DecrementRecursionDepth() { recursion_depth_--; }
857
848 private: 858 private:
849 EndNode* accept_; 859 EndNode* accept_;
850 EndNode* backtrack_; 860 EndNode* backtrack_;
851 int next_register_; 861 int next_register_;
852 List<RegExpNode*>* work_list_; 862 List<RegExpNode*>* work_list_;
863 int recursion_depth_;
853 RegExpMacroAssembler* macro_assembler_; 864 RegExpMacroAssembler* macro_assembler_;
854 }; 865 };
855 866
856 867
857 // Attempts to compile the regexp using a Regexp2000 code generator. Returns 868 // Attempts to compile the regexp using a Regexp2000 code generator. Returns
858 // a fixed array or a null handle depending on whether it succeeded. 869 // a fixed array or a null handle depending on whether it succeeded.
859 RegExpCompiler::RegExpCompiler(int capture_count) 870 RegExpCompiler::RegExpCompiler(int capture_count)
860 : next_register_(2 * capture_count), 871 : next_register_(2 * (capture_count + 1)),
861 work_list_(NULL) { 872 work_list_(NULL),
873 recursion_depth_(0) {
862 accept_ = new EndNode(EndNode::ACCEPT); 874 accept_ = new EndNode(EndNode::ACCEPT);
863 backtrack_ = new EndNode(EndNode::BACKTRACK); 875 backtrack_ = new EndNode(EndNode::BACKTRACK);
864 } 876 }
865 877
866 878
867 Handle<FixedArray> RegExpCompiler::Assemble( 879 Handle<FixedArray> RegExpCompiler::Assemble(
868 RegExpMacroAssembler* macro_assembler, 880 RegExpMacroAssembler* macro_assembler,
869 RegExpNode* start, 881 RegExpNode* start,
870 int capture_count, 882 int capture_count,
871 bool case_independent) { 883 bool case_independent) {
872 if (case_independent) return Handle<FixedArray>::null(); 884 if (case_independent) return Handle<FixedArray>::null();
873 macro_assembler_ = macro_assembler; 885 macro_assembler_ = macro_assembler;
874 List <RegExpNode*> work_list(0); 886 List <RegExpNode*> work_list(0);
875 work_list_ = &work_list; 887 work_list_ = &work_list;
876 Label fail; 888 Label fail;
877 macro_assembler->PushBacktrack(&fail); 889 macro_assembler->PushBacktrack(&fail);
878 if (!start->GoTo(this)) { 890 if (!start->GoTo(this)) {
879 fail.Unuse(); 891 fail.Unuse();
880 return Handle<FixedArray>::null(); 892 return Handle<FixedArray>::null();
881 } 893 }
882 while (!work_list.is_empty()) { 894 while (!work_list.is_empty()) {
883 if (!work_list.RemoveLast()->Emit(this)) { 895 if (!work_list.RemoveLast()->GoTo(this)) {
884 fail.Unuse(); 896 fail.Unuse();
885 return Handle<FixedArray>::null(); 897 return Handle<FixedArray>::null();
886 } 898 }
887 } 899 }
888 macro_assembler->Bind(&fail); 900 macro_assembler->Bind(&fail);
889 macro_assembler->Fail(); 901 macro_assembler->Fail();
890 Handle<FixedArray> array = 902 Handle<FixedArray> array =
891 Factory::NewFixedArray(RegExpImpl::kRe2kDataLength); 903 Factory::NewFixedArray(RegExpImpl::kRe2kDataLength);
892 array->set(RegExpImpl::kRe2kImplementationIndex, 904 array->set(RegExpImpl::kRe2kImplementationIndex,
893 Smi::FromInt(macro_assembler->Implementation())); 905 Smi::FromInt(macro_assembler->Implementation()));
894 array->set(RegExpImpl::kRe2kNumberOfRegistersIndex, 906 array->set(RegExpImpl::kRe2kNumberOfRegistersIndex,
895 Smi::FromInt(next_register_)); 907 Smi::FromInt(next_register_));
896 array->set(RegExpImpl::kRe2kNumberOfCapturesIndex, 908 array->set(RegExpImpl::kRe2kNumberOfCapturesIndex,
897 Smi::FromInt(capture_count)); 909 Smi::FromInt(capture_count));
898 Handle<Object> code = macro_assembler->GetCode(); 910 Handle<Object> code = macro_assembler->GetCode();
899 array->set(RegExpImpl::kRe2kCodeIndex, *code); 911 array->set(RegExpImpl::kRe2kCodeIndex, *code);
900 work_list_ = NULL; 912 work_list_ = NULL;
901 return array; 913 return array;
902 } 914 }
903 915
904 916
905 bool RegExpNode::GoTo(RegExpCompiler* compiler) { 917 bool RegExpNode::GoTo(RegExpCompiler* compiler) {
918 // TODO(erikcorry): Implement support.
919 if (info_.follows_word_interest ||
920 info_.follows_newline_interest ||
921 info_.follows_start_interest) {
922 return false;
923 }
906 if (label_.is_bound()) { 924 if (label_.is_bound()) {
907 compiler->macro_assembler()->GoTo(&label_); 925 compiler->macro_assembler()->GoTo(&label_);
908 return true; 926 return true;
909 } else { 927 } else {
910 return Emit(compiler); 928 if (compiler->recursion_depth() > RegExpCompiler::kMaxRecursion) {
929 compiler->macro_assembler()->GoTo(&label_);
930 compiler->AddWork(this);
931 return true;
932 } else {
933 compiler->IncrementRecursionDepth();
934 bool how_it_went = Emit(compiler);
935 compiler->DecrementRecursionDepth();
936 return how_it_went;
937 }
911 } 938 }
912 } 939 }
913 940
914 941
942 bool EndNode::GoTo(RegExpCompiler* compiler) {
943 if (info()->follows_word_interest ||
944 info()->follows_newline_interest ||
945 info()->follows_start_interest) {
946 return false;
947 }
948 if (!label()->is_bound()) {
949 Bind(compiler->macro_assembler());
950 }
951 switch (action_) {
952 case ACCEPT:
953 compiler->macro_assembler()->Succeed();
954 break;
955 case BACKTRACK:
956 compiler->macro_assembler()->Backtrack();
957 break;
958 }
959 return true;
960 }
961
962
915 Label* RegExpNode::label() { 963 Label* RegExpNode::label() {
916 return &label_; 964 return &label_;
917 } 965 }
918 966
919 967
920 bool EndNode::Emit(RegExpCompiler* compiler) { 968 bool EndNode::Emit(RegExpCompiler* compiler) {
969 RegExpMacroAssembler* macro = compiler->macro_assembler();
921 switch (action_) { 970 switch (action_) {
922 case ACCEPT: 971 case ACCEPT:
923 compiler->macro_assembler()->Succeed(); 972 Bind(macro);
973 macro->Succeed();
924 return true; 974 return true;
925 case BACKTRACK: 975 case BACKTRACK:
926 compiler->macro_assembler()->Backtrack(); 976 Bind(macro);
977 macro->Backtrack();
927 return true; 978 return true;
928 } 979 }
929 return false; 980 return false;
930 } 981 }
931 982
932 983
933 void GuardedAlternative::AddGuard(Guard* guard) { 984 void GuardedAlternative::AddGuard(Guard* guard) {
934 if (guards_ == NULL) 985 if (guards_ == NULL)
935 guards_ = new ZoneList<Guard*>(1); 986 guards_ = new ZoneList<Guard*>(1);
936 guards_->Add(guard); 987 guards_->Add(guard);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 visitor->Visit##Type(this); \ 1039 visitor->Visit##Type(this); \
989 } 1040 }
990 FOR_EACH_NODE_TYPE(DEFINE_ACCEPT) 1041 FOR_EACH_NODE_TYPE(DEFINE_ACCEPT)
991 #undef DEFINE_ACCEPT 1042 #undef DEFINE_ACCEPT
992 1043
993 1044
994 // ------------------------------------------------------------------- 1045 // -------------------------------------------------------------------
995 // Emit code. 1046 // Emit code.
996 1047
997 1048
998 void ChoiceNode::GenerateGuard(RegExpCompiler* compiler, 1049 void ChoiceNode::GenerateGuard(RegExpMacroAssembler* macro_assembler,
999 Guard *guard, 1050 Guard* guard,
1000 Label* on_failure) { 1051 Label* on_failure) {
1052 switch (guard->op()) {
1053 case Guard::LT:
1054 macro_assembler->IfRegisterGE(guard->reg(), guard->value(), on_failure);
1055 break;
1056 case Guard::GEQ:
1057 macro_assembler->IfRegisterLT(guard->reg(), guard->value(), on_failure);
1058 break;
1059 }
1060 }
1061
1062
1063 bool TextNode::Emit(RegExpCompiler* compiler) {
1064 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
1065 Bind(macro_assembler);
1066 int element_count = elms_->length();
1067 int cp_offset = 0;
1068 for (int i = 0; i < element_count; i++) {
1069 TextElement elm = (*elms_)[i];
1070 switch (elm.type) {
1071 case TextElement::ATOM: {
1072 Vector<const uc16> quarks = elm.data.u_atom->data();
1073 macro_assembler->CheckCharacters(quarks,
1074 cp_offset,
1075 on_failure_->label());
1076 cp_offset += quarks.length();
1077 break;
1078 }
1079 case TextElement::CHAR_CLASS: {
1080 RegExpCharacterClass* cc = elm.data.u_char_class;
1081 if (cc->is_negated()) return false;
1082 macro_assembler->LoadCurrentCharacter(cp_offset, on_failure_->label());
1083 cp_offset++;
1084
1085 ZoneList<CharacterRange>* ranges = cc->ranges();
1086
1087 Label found;
1088
1089 int range_count = ranges->length();
1090
1091 if (range_count == 0) {
1092 on_failure()->GoTo(compiler);
1093 break;
1094 }
1095
1096 for (int i = 0; i < range_count - 1; i++) {
1097 CharacterRange& range = (*ranges)[i];
1098 Label next_range;
1099 uc16 from = range.from();
1100 uc16 to = range.to();
1101 if (from != 0) {
1102 macro_assembler->CheckCharacterLT(from, &next_range);
1103 }
1104 if (to != 0xffff) {
1105 macro_assembler->CheckCharacterLT(to + 1, &found);
1106 } else {
1107 macro_assembler->AdvanceCurrentPosition(1);
1108 on_success()->GoTo(compiler);
1109 }
1110 macro_assembler->Bind(&next_range);
1111 }
1112
1113 CharacterRange& range = (*ranges)[range_count - 1];
1114 uc16 from = range.from();
1115 uc16 to = range.to();
1116 if (from != 0) {
1117 macro_assembler->CheckCharacterLT(from, on_failure_->label());
1118 }
1119 if (to != 0xffff) {
1120 macro_assembler->CheckCharacterGT(to, on_failure_->label());
1121 }
1122 compiler->AddWork(on_failure_);
1123 macro_assembler->Bind(&found);
1124 break;
1125 }
1126 default:
1127 UNREACHABLE();
1128 return false;
1129 }
1130 }
1131 macro_assembler->AdvanceCurrentPosition(cp_offset);
1132 return on_success()->GoTo(compiler);
1001 } 1133 }
1002 1134
1003 1135
1004 bool ChoiceNode::Emit(RegExpCompiler* compiler) { 1136 bool ChoiceNode::Emit(RegExpCompiler* compiler) {
1005 int choice_count = alternatives_->length(); 1137 int choice_count = alternatives_->length();
1006 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler(); 1138 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
1139 Bind(macro_assembler);
1007 // For now we just call all choices one after the other. The idea ultimately 1140 // For now we just call all choices one after the other. The idea ultimately
1008 // is to use the Dispatch table to try only the relevant ones. 1141 // is to use the Dispatch table to try only the relevant ones.
1009 for (int i = 0; i < choice_count; i++) { 1142 int i;
1143 for (i = 0; i < choice_count - 1; i++) {
1010 GuardedAlternative alternative = (*alternatives_)[i]; 1144 GuardedAlternative alternative = (*alternatives_)[i];
1011 Label after; 1145 Label after;
1012 Label* next_alternative; 1146 Label after_no_pop_cp;
1013 if (i < choice_count - 1) {
1014 next_alternative = &after;
1015 } else {
1016 next_alternative = on_failure_->label();
1017 }
1018 ZoneList<Guard*>* guards = alternative.guards(); 1147 ZoneList<Guard*>* guards = alternative.guards();
1019 if (guards != NULL) { 1148 if (guards != NULL) {
1020 int guard_count = guards->length(); 1149 int guard_count = guards->length();
1021 for (int j = 0; j < guard_count; j++) { 1150 for (int j = 0; j < guard_count; j++) {
1022 GenerateGuard(compiler, (*guards)[i], next_alternative); 1151 GenerateGuard(macro_assembler, (*guards)[j], &after_no_pop_cp);
1023 } 1152 }
1024 } 1153 }
1025 macro_assembler->PushBacktrack(next_alternative); 1154 macro_assembler->PushCurrentPosition();
1026 if (!alternative.node()->Emit(compiler)) { 1155 macro_assembler->PushBacktrack(&after);
1156 if (!alternative.node()->GoTo(compiler)) {
1027 after.Unuse(); 1157 after.Unuse();
1028 if (next_alternative != &after) { 1158 after_no_pop_cp.Unuse();
1029 next_alternative->Unuse();
1030 }
1031 return false; 1159 return false;
1032 } 1160 }
1033 if (i < choice_count - 1) { 1161 macro_assembler->Bind(&after);
1034 macro_assembler->Bind(&after); 1162 macro_assembler->PopCurrentPosition();
1035 } else { 1163 macro_assembler->Bind(&after_no_pop_cp);
1036 after.Unuse(); 1164 }
1165 GuardedAlternative alternative = (*alternatives_)[i];
1166 ZoneList<Guard*>* guards = alternative.guards();
1167 if (guards != NULL) {
1168 int guard_count = guards->length();
1169 for (int j = 0; j < guard_count; j++) {
1170 GenerateGuard(macro_assembler, (*guards)[j], on_failure_->label());
1037 } 1171 }
1038 } 1172 }
1173 if (!on_failure_->IsBacktrack()) {
1174 macro_assembler->PushBacktrack(on_failure_->label());
1175 }
1176 if (!alternative.node()->GoTo(compiler)) {
1177 return false;
1178 }
1039 compiler->AddWork(on_failure_); 1179 compiler->AddWork(on_failure_);
1040 return true; 1180 return true;
1041 } 1181 }
1042 1182
1043 1183
1044 bool ActionNode::Emit(RegExpCompiler* compiler) { 1184 bool ActionNode::Emit(RegExpCompiler* compiler) {
1045 RegExpMacroAssembler* macro = compiler->macro_assembler(); 1185 RegExpMacroAssembler* macro = compiler->macro_assembler();
1186 Bind(macro);
1046 switch (type_) { 1187 switch (type_) {
1047 case STORE_REGISTER: 1188 case STORE_REGISTER:
1048 macro->SetRegister(data_.u_store_register.reg, 1189 macro->SetRegister(data_.u_store_register.reg,
1049 data_.u_store_register.value); 1190 data_.u_store_register.value);
1050 break; 1191 break;
1051 case INCREMENT_REGISTER: 1192 case INCREMENT_REGISTER: {
1193 Label undo;
1194 macro->PushBacktrack(&undo);
1052 macro->AdvanceRegister(data_.u_increment_register.reg, 1); 1195 macro->AdvanceRegister(data_.u_increment_register.reg, 1);
1196 bool ok = on_success()->GoTo(compiler);
1197 if (!ok) {
1198 undo.Unuse();
1199 return false;
1200 }
1201 macro->Bind(&undo);
1202 macro->AdvanceRegister(data_.u_increment_register.reg, -1);
1203 macro->Backtrack();
1053 break; 1204 break;
1054 case STORE_POSITION: 1205 }
1055 macro->PushCurrentPosition(); 1206 case STORE_POSITION: {
1207 Label undo;
1208 macro->PushRegister(data_.u_position_register.reg);
1209 macro->PushBacktrack(&undo);
1210 macro->WriteCurrentPositionToRegister(data_.u_position_register.reg);
1211 bool ok = on_success()->GoTo(compiler);
1212 if (!ok) {
1213 undo.Unuse();
1214 return false;
1215 }
1216 macro->Bind(&undo);
1217 macro->PopRegister(data_.u_position_register.reg);
1218 macro->Backtrack();
1056 break; 1219 break;
1220 }
1057 case RESTORE_POSITION: 1221 case RESTORE_POSITION:
1058 macro->PopCurrentPosition(); 1222 // TODO(erikcorry): Implement this.
1059 break; 1223 return false;
1060 case BEGIN_SUBMATCH: 1224 case BEGIN_SUBMATCH:
1061 // TODO(erikcorry): Implement this. 1225 // TODO(erikcorry): Implement this.
1062 return false; 1226 return false;
1063 case ESCAPE_SUBMATCH: 1227 case ESCAPE_SUBMATCH:
1064 // TODO(erikcorry): Implement this. 1228 // TODO(erikcorry): Implement this.
1065 return false; 1229 return false;
1066 case END_SUBMATCH: 1230 case END_SUBMATCH:
1067 // TODO(erikcorry): Implement this. 1231 // TODO(erikcorry): Implement this.
1068 return false; 1232 return false;
1069 default: 1233 default:
1070 UNREACHABLE(); 1234 UNREACHABLE();
1071 return false; 1235 return false;
1072 } 1236 }
1073 compiler->AddWork(on_success()); 1237 return on_success()->GoTo(compiler);
1074 return true;
1075 } 1238 }
1076 1239
1077 1240
1078 // ------------------------------------------------------------------- 1241 // -------------------------------------------------------------------
1079 // Dot/dotty output 1242 // Dot/dotty output
1080 1243
1081 1244
1082 #ifdef DEBUG 1245 #ifdef DEBUG
1083 1246
1084 1247
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
1558 RegExpNode* current = on_success; 1721 RegExpNode* current = on_success;
1559 for (int i = children->length() - 1; i >= 0; i--) { 1722 for (int i = children->length() - 1; i >= 0; i--) {
1560 current = children->at(i)->ToNode(compiler, current, on_failure); 1723 current = children->at(i)->ToNode(compiler, current, on_failure);
1561 } 1724 }
1562 return current; 1725 return current;
1563 } 1726 }
1564 1727
1565 1728
1566 static const int kSpaceRangeCount = 20; 1729 static const int kSpaceRangeCount = 20;
1567 static const uc16 kSpaceRanges[kSpaceRangeCount] = { 1730 static const uc16 kSpaceRanges[kSpaceRangeCount] = {
1568 0x0009, 0x0009, 0x000B, 0x000C, 0x0020, 0x0020, 0x00A0, 0x00A0, 1731 0x0009, 0x000D, 0x0020, 0x0020, 0x00A0, 0x00A0, 0x1680,
1569 0x1680, 0x1680, 0x180E, 0x180E, 0x2000, 0x200A, 0x202F, 0x202F, 1732 0x1680, 0x180E, 0x180E, 0x2000, 0x200A, 0x2028, 0x2029,
1570 0x205F, 0x205F, 0x3000, 0x3000 1733 0x202F, 0x202F, 0x205F, 0x205F, 0x3000, 0x3000
1571 }; 1734 };
1572 1735
1573 1736
1574 static const int kWordRangeCount = 8; 1737 static const int kWordRangeCount = 8;
1575 static const uc16 kWordRanges[kWordRangeCount] = { 1738 static const uc16 kWordRanges[kWordRangeCount] = {
1576 '0', '9', 'A', 'Z', '_', '_', 'a', 'z' 1739 '0', '9', 'A', 'Z', '_', '_', 'a', 'z'
1577 }; 1740 };
1578 1741
1579 1742
1580 static const int kDigitRangeCount = 2; 1743 static const int kDigitRangeCount = 2;
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
1962 DispatchTableConstructor constructor(node->table()); 2125 DispatchTableConstructor constructor(node->table());
1963 constructor.BuildTable(node); 2126 constructor.BuildTable(node);
1964 } 2127 }
1965 ASSERT(node->table_calculated()); 2128 ASSERT(node->table_calculated());
1966 AddDispatchRange adder(this); 2129 AddDispatchRange adder(this);
1967 node->table()->ForEach(&adder); 2130 node->table()->ForEach(&adder);
1968 } 2131 }
1969 2132
1970 2133
1971 void DispatchTableConstructor::VisitBackreference(BackreferenceNode* that) { 2134 void DispatchTableConstructor::VisitBackreference(BackreferenceNode* that) {
1972 UNIMPLEMENTED(); 2135 // TODO(plesner): What should this do?
1973 } 2136 }
1974 2137
1975 2138
1976 2139
1977 static int CompareRangeByFrom(const CharacterRange* a, 2140 static int CompareRangeByFrom(const CharacterRange* a,
1978 const CharacterRange* b) { 2141 const CharacterRange* b) {
1979 return Spaceship<uc16>(a->from(), b->from()); 2142 return Spaceship<uc16>(a->from(), b->from());
1980 } 2143 }
1981 2144
1982 2145
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2048 RegExpNode* node = RegExpQuantifier::ToNode(0, 2211 RegExpNode* node = RegExpQuantifier::ToNode(0,
2049 RegExpQuantifier::kInfinity, 2212 RegExpQuantifier::kInfinity,
2050 false, 2213 false,
2051 new RegExpCharacterClass('.'), 2214 new RegExpCharacterClass('.'),
2052 &compiler, 2215 &compiler,
2053 captured_body, 2216 captured_body,
2054 compiler.backtrack()); 2217 compiler.backtrack());
2055 if (node_return != NULL) *node_return = node; 2218 if (node_return != NULL) *node_return = node;
2056 Analysis analysis; 2219 Analysis analysis;
2057 analysis.EnsureAnalyzed(node); 2220 analysis.EnsureAnalyzed(node);
2058 byte codes[10240]; 2221 byte codes[1024];
2059 Re2kAssembler assembler(Vector<byte>(codes, 1024)); 2222 Re2kAssembler assembler(Vector<byte>(codes, 1024));
2060 RegExpMacroAssemblerRe2k macro_assembler(&assembler); 2223 RegExpMacroAssemblerRe2k macro_assembler(&assembler);
2061 return compiler.Assemble(&macro_assembler, 2224 return compiler.Assemble(&macro_assembler,
2062 node, 2225 node,
2063 input->capture_count, 2226 input->capture_count,
2064 ignore_case); 2227 ignore_case);
2065 } 2228 }
2066 2229
2067 RegExpMacroAssembler::RegExpMacroAssembler() { 2230 RegExpMacroAssembler::RegExpMacroAssembler() {
2068 } 2231 }
2069 2232
2070 RegExpMacroAssembler::~RegExpMacroAssembler() { 2233 RegExpMacroAssembler::~RegExpMacroAssembler() {
2071 } 2234 }
2072 2235
2073 2236
2074 }} // namespace v8::internal 2237 }} // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698