| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 932 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 943 | 943 | 
| 944 TextElement TextElement::CharClass( | 944 TextElement TextElement::CharClass( | 
| 945       RegExpCharacterClass* char_class) { | 945       RegExpCharacterClass* char_class) { | 
| 946   TextElement result = TextElement(CHAR_CLASS); | 946   TextElement result = TextElement(CHAR_CLASS); | 
| 947   result.data.u_char_class = char_class; | 947   result.data.u_char_class = char_class; | 
| 948   return result; | 948   return result; | 
| 949 } | 949 } | 
| 950 | 950 | 
| 951 | 951 | 
| 952 int TextElement::length() { | 952 int TextElement::length() { | 
| 953   if (type == ATOM) { | 953   if (text_type == ATOM) { | 
| 954     return data.u_atom->length(); | 954     return data.u_atom->length(); | 
| 955   } else { | 955   } else { | 
| 956     ASSERT(type == CHAR_CLASS); | 956     ASSERT(text_type == CHAR_CLASS); | 
| 957     return 1; | 957     return 1; | 
| 958   } | 958   } | 
| 959 } | 959 } | 
| 960 | 960 | 
| 961 | 961 | 
| 962 DispatchTable* ChoiceNode::GetTable(bool ignore_case) { | 962 DispatchTable* ChoiceNode::GetTable(bool ignore_case) { | 
| 963   if (table_ == NULL) { | 963   if (table_ == NULL) { | 
| 964     table_ = new(zone()) DispatchTable(zone()); | 964     table_ = new(zone()) DispatchTable(zone()); | 
| 965     DispatchTableConstructor cons(table_, ignore_case, zone()); | 965     DispatchTableConstructor cons(table_, ignore_case, zone()); | 
| 966     cons.BuildTable(this); | 966     cons.BuildTable(this); | 
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1158   } | 1158   } | 
| 1159   if (FLAG_trace_regexp_assembler) { | 1159   if (FLAG_trace_regexp_assembler) { | 
| 1160     delete macro_assembler_; | 1160     delete macro_assembler_; | 
| 1161   } | 1161   } | 
| 1162 #endif | 1162 #endif | 
| 1163   return RegExpEngine::CompilationResult(*code, next_register_); | 1163   return RegExpEngine::CompilationResult(*code, next_register_); | 
| 1164 } | 1164 } | 
| 1165 | 1165 | 
| 1166 | 1166 | 
| 1167 bool Trace::DeferredAction::Mentions(int that) { | 1167 bool Trace::DeferredAction::Mentions(int that) { | 
| 1168   if (type() == ActionNode::CLEAR_CAPTURES) { | 1168   if (action_type() == ActionNode::CLEAR_CAPTURES) { | 
| 1169     Interval range = static_cast<DeferredClearCaptures*>(this)->range(); | 1169     Interval range = static_cast<DeferredClearCaptures*>(this)->range(); | 
| 1170     return range.Contains(that); | 1170     return range.Contains(that); | 
| 1171   } else { | 1171   } else { | 
| 1172     return reg() == that; | 1172     return reg() == that; | 
| 1173   } | 1173   } | 
| 1174 } | 1174 } | 
| 1175 | 1175 | 
| 1176 | 1176 | 
| 1177 bool Trace::mentions_reg(int reg) { | 1177 bool Trace::mentions_reg(int reg) { | 
| 1178   for (DeferredAction* action = actions_; | 1178   for (DeferredAction* action = actions_; | 
| 1179        action != NULL; | 1179        action != NULL; | 
| 1180        action = action->next()) { | 1180        action = action->next()) { | 
| 1181     if (action->Mentions(reg)) | 1181     if (action->Mentions(reg)) | 
| 1182       return true; | 1182       return true; | 
| 1183   } | 1183   } | 
| 1184   return false; | 1184   return false; | 
| 1185 } | 1185 } | 
| 1186 | 1186 | 
| 1187 | 1187 | 
| 1188 bool Trace::GetStoredPosition(int reg, int* cp_offset) { | 1188 bool Trace::GetStoredPosition(int reg, int* cp_offset) { | 
| 1189   ASSERT_EQ(0, *cp_offset); | 1189   ASSERT_EQ(0, *cp_offset); | 
| 1190   for (DeferredAction* action = actions_; | 1190   for (DeferredAction* action = actions_; | 
| 1191        action != NULL; | 1191        action != NULL; | 
| 1192        action = action->next()) { | 1192        action = action->next()) { | 
| 1193     if (action->Mentions(reg)) { | 1193     if (action->Mentions(reg)) { | 
| 1194       if (action->type() == ActionNode::STORE_POSITION) { | 1194       if (action->action_type() == ActionNode::STORE_POSITION) { | 
| 1195         *cp_offset = static_cast<DeferredCapture*>(action)->cp_offset(); | 1195         *cp_offset = static_cast<DeferredCapture*>(action)->cp_offset(); | 
| 1196         return true; | 1196         return true; | 
| 1197       } else { | 1197       } else { | 
| 1198         return false; | 1198         return false; | 
| 1199       } | 1199       } | 
| 1200     } | 1200     } | 
| 1201   } | 1201   } | 
| 1202   return false; | 1202   return false; | 
| 1203 } | 1203 } | 
| 1204 | 1204 | 
| 1205 | 1205 | 
| 1206 int Trace::FindAffectedRegisters(OutSet* affected_registers, | 1206 int Trace::FindAffectedRegisters(OutSet* affected_registers, | 
| 1207                                  Zone* zone) { | 1207                                  Zone* zone) { | 
| 1208   int max_register = RegExpCompiler::kNoRegister; | 1208   int max_register = RegExpCompiler::kNoRegister; | 
| 1209   for (DeferredAction* action = actions_; | 1209   for (DeferredAction* action = actions_; | 
| 1210        action != NULL; | 1210        action != NULL; | 
| 1211        action = action->next()) { | 1211        action = action->next()) { | 
| 1212     if (action->type() == ActionNode::CLEAR_CAPTURES) { | 1212     if (action->action_type() == ActionNode::CLEAR_CAPTURES) { | 
| 1213       Interval range = static_cast<DeferredClearCaptures*>(action)->range(); | 1213       Interval range = static_cast<DeferredClearCaptures*>(action)->range(); | 
| 1214       for (int i = range.from(); i <= range.to(); i++) | 1214       for (int i = range.from(); i <= range.to(); i++) | 
| 1215         affected_registers->Set(i, zone); | 1215         affected_registers->Set(i, zone); | 
| 1216       if (range.to() > max_register) max_register = range.to(); | 1216       if (range.to() > max_register) max_register = range.to(); | 
| 1217     } else { | 1217     } else { | 
| 1218       affected_registers->Set(action->reg(), zone); | 1218       affected_registers->Set(action->reg(), zone); | 
| 1219       if (action->reg() > max_register) max_register = action->reg(); | 1219       if (action->reg() > max_register) max_register = action->reg(); | 
| 1220     } | 1220     } | 
| 1221   } | 1221   } | 
| 1222   return max_register; | 1222   return max_register; | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1266     int value = 0; | 1266     int value = 0; | 
| 1267     bool absolute = false; | 1267     bool absolute = false; | 
| 1268     bool clear = false; | 1268     bool clear = false; | 
| 1269     int store_position = -1; | 1269     int store_position = -1; | 
| 1270     // This is a little tricky because we are scanning the actions in reverse | 1270     // This is a little tricky because we are scanning the actions in reverse | 
| 1271     // historical order (newest first). | 1271     // historical order (newest first). | 
| 1272     for (DeferredAction* action = actions_; | 1272     for (DeferredAction* action = actions_; | 
| 1273          action != NULL; | 1273          action != NULL; | 
| 1274          action = action->next()) { | 1274          action = action->next()) { | 
| 1275       if (action->Mentions(reg)) { | 1275       if (action->Mentions(reg)) { | 
| 1276         switch (action->type()) { | 1276         switch (action->action_type()) { | 
| 1277           case ActionNode::SET_REGISTER: { | 1277           case ActionNode::SET_REGISTER: { | 
| 1278             Trace::DeferredSetRegister* psr = | 1278             Trace::DeferredSetRegister* psr = | 
| 1279                 static_cast<Trace::DeferredSetRegister*>(action); | 1279                 static_cast<Trace::DeferredSetRegister*>(action); | 
| 1280             if (!absolute) { | 1280             if (!absolute) { | 
| 1281               value += psr->value(); | 1281               value += psr->value(); | 
| 1282               absolute = true; | 1282               absolute = true; | 
| 1283             } | 1283             } | 
| 1284             // SET_REGISTER is currently only used for newly introduced loop | 1284             // SET_REGISTER is currently only used for newly introduced loop | 
| 1285             // counters. They can have a significant previous value if they | 1285             // counters. They can have a significant previous value if they | 
| 1286             // occour in a loop. TODO(lrn): Propagate this information, so | 1286             // occour in a loop. TODO(lrn): Propagate this information, so | 
| (...skipping 1010 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2297   // generic versions above can handle deep recursion properly. | 2297   // generic versions above can handle deep recursion properly. | 
| 2298   trace->Flush(compiler, this); | 2298   trace->Flush(compiler, this); | 
| 2299   return DONE; | 2299   return DONE; | 
| 2300 } | 2300 } | 
| 2301 | 2301 | 
| 2302 | 2302 | 
| 2303 int ActionNode::EatsAtLeast(int still_to_find, | 2303 int ActionNode::EatsAtLeast(int still_to_find, | 
| 2304                             int budget, | 2304                             int budget, | 
| 2305                             bool not_at_start) { | 2305                             bool not_at_start) { | 
| 2306   if (budget <= 0) return 0; | 2306   if (budget <= 0) return 0; | 
| 2307   if (type_ == POSITIVE_SUBMATCH_SUCCESS) return 0;  // Rewinds input! | 2307   if (action_type_ == POSITIVE_SUBMATCH_SUCCESS) return 0;  // Rewinds input! | 
| 2308   return on_success()->EatsAtLeast(still_to_find, | 2308   return on_success()->EatsAtLeast(still_to_find, | 
| 2309                                    budget - 1, | 2309                                    budget - 1, | 
| 2310                                    not_at_start); | 2310                                    not_at_start); | 
| 2311 } | 2311 } | 
| 2312 | 2312 | 
| 2313 | 2313 | 
| 2314 void ActionNode::FillInBMInfo(int offset, | 2314 void ActionNode::FillInBMInfo(int offset, | 
| 2315                               int budget, | 2315                               int budget, | 
| 2316                               BoyerMooreLookahead* bm, | 2316                               BoyerMooreLookahead* bm, | 
| 2317                               bool not_at_start) { | 2317                               bool not_at_start) { | 
| 2318   if (type_ == BEGIN_SUBMATCH) { | 2318   if (action_type_ == BEGIN_SUBMATCH) { | 
| 2319     bm->SetRest(offset); | 2319     bm->SetRest(offset); | 
| 2320   } else if (type_ != POSITIVE_SUBMATCH_SUCCESS) { | 2320   } else if (action_type_ != POSITIVE_SUBMATCH_SUCCESS) { | 
| 2321     on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start); | 2321     on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start); | 
| 2322   } | 2322   } | 
| 2323   SaveBMInfo(bm, not_at_start, offset); | 2323   SaveBMInfo(bm, not_at_start, offset); | 
| 2324 } | 2324 } | 
| 2325 | 2325 | 
| 2326 | 2326 | 
| 2327 int AssertionNode::EatsAtLeast(int still_to_find, | 2327 int AssertionNode::EatsAtLeast(int still_to_find, | 
| 2328                                int budget, | 2328                                int budget, | 
| 2329                                bool not_at_start) { | 2329                                bool not_at_start) { | 
| 2330   if (budget <= 0) return 0; | 2330   if (budget <= 0) return 0; | 
| 2331   // If we know we are not at the start and we are asked "how many characters | 2331   // If we know we are not at the start and we are asked "how many characters | 
| 2332   // will you match if you succeed?" then we can answer anything since false | 2332   // will you match if you succeed?" then we can answer anything since false | 
| 2333   // implies false.  So lets just return the max answer (still_to_find) since | 2333   // implies false.  So lets just return the max answer (still_to_find) since | 
| 2334   // that won't prevent us from preloading a lot of characters for the other | 2334   // that won't prevent us from preloading a lot of characters for the other | 
| 2335   // branches in the node graph. | 2335   // branches in the node graph. | 
| 2336   if (type() == AT_START && not_at_start) return still_to_find; | 2336   if (assertion_type() == AT_START && not_at_start) return still_to_find; | 
| 2337   return on_success()->EatsAtLeast(still_to_find, | 2337   return on_success()->EatsAtLeast(still_to_find, | 
| 2338                                    budget - 1, | 2338                                    budget - 1, | 
| 2339                                    not_at_start); | 2339                                    not_at_start); | 
| 2340 } | 2340 } | 
| 2341 | 2341 | 
| 2342 | 2342 | 
| 2343 void AssertionNode::FillInBMInfo(int offset, | 2343 void AssertionNode::FillInBMInfo(int offset, | 
| 2344                                  int budget, | 2344                                  int budget, | 
| 2345                                  BoyerMooreLookahead* bm, | 2345                                  BoyerMooreLookahead* bm, | 
| 2346                                  bool not_at_start) { | 2346                                  bool not_at_start) { | 
| 2347   // Match the behaviour of EatsAtLeast on this node. | 2347   // Match the behaviour of EatsAtLeast on this node. | 
| 2348   if (type() == AT_START && not_at_start) return; | 2348   if (assertion_type() == AT_START && not_at_start) return; | 
| 2349   on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start); | 2349   on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start); | 
| 2350   SaveBMInfo(bm, not_at_start, offset); | 2350   SaveBMInfo(bm, not_at_start, offset); | 
| 2351 } | 2351 } | 
| 2352 | 2352 | 
| 2353 | 2353 | 
| 2354 int BackReferenceNode::EatsAtLeast(int still_to_find, | 2354 int BackReferenceNode::EatsAtLeast(int still_to_find, | 
| 2355                                    int budget, | 2355                                    int budget, | 
| 2356                                    bool not_at_start) { | 2356                                    bool not_at_start) { | 
| 2357   if (budget <= 0) return 0; | 2357   if (budget <= 0) return 0; | 
| 2358   return on_success()->EatsAtLeast(still_to_find, | 2358   return on_success()->EatsAtLeast(still_to_find, | 
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2555   ASSERT(characters_filled_in < details->characters()); | 2555   ASSERT(characters_filled_in < details->characters()); | 
| 2556   int characters = details->characters(); | 2556   int characters = details->characters(); | 
| 2557   int char_mask; | 2557   int char_mask; | 
| 2558   if (compiler->ascii()) { | 2558   if (compiler->ascii()) { | 
| 2559     char_mask = String::kMaxOneByteCharCode; | 2559     char_mask = String::kMaxOneByteCharCode; | 
| 2560   } else { | 2560   } else { | 
| 2561     char_mask = String::kMaxUtf16CodeUnit; | 2561     char_mask = String::kMaxUtf16CodeUnit; | 
| 2562   } | 2562   } | 
| 2563   for (int k = 0; k < elms_->length(); k++) { | 2563   for (int k = 0; k < elms_->length(); k++) { | 
| 2564     TextElement elm = elms_->at(k); | 2564     TextElement elm = elms_->at(k); | 
| 2565     if (elm.type == TextElement::ATOM) { | 2565     if (elm.text_type == TextElement::ATOM) { | 
| 2566       Vector<const uc16> quarks = elm.data.u_atom->data(); | 2566       Vector<const uc16> quarks = elm.data.u_atom->data(); | 
| 2567       for (int i = 0; i < characters && i < quarks.length(); i++) { | 2567       for (int i = 0; i < characters && i < quarks.length(); i++) { | 
| 2568         QuickCheckDetails::Position* pos = | 2568         QuickCheckDetails::Position* pos = | 
| 2569             details->positions(characters_filled_in); | 2569             details->positions(characters_filled_in); | 
| 2570         uc16 c = quarks[i]; | 2570         uc16 c = quarks[i]; | 
| 2571         if (c > char_mask) { | 2571         if (c > char_mask) { | 
| 2572           // If we expect a non-ASCII character from an ASCII string, | 2572           // If we expect a non-ASCII character from an ASCII string, | 
| 2573           // there is no way we can match. Not even case independent | 2573           // there is no way we can match. Not even case independent | 
| 2574           // matching can turn an ASCII character into non-ASCII or | 2574           // matching can turn an ASCII character into non-ASCII or | 
| 2575           // vice versa. | 2575           // vice versa. | 
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2808 | 2808 | 
| 2809 | 2809 | 
| 2810 RegExpNode* TextNode::FilterASCII(int depth, bool ignore_case) { | 2810 RegExpNode* TextNode::FilterASCII(int depth, bool ignore_case) { | 
| 2811   if (info()->replacement_calculated) return replacement(); | 2811   if (info()->replacement_calculated) return replacement(); | 
| 2812   if (depth < 0) return this; | 2812   if (depth < 0) return this; | 
| 2813   ASSERT(!info()->visited); | 2813   ASSERT(!info()->visited); | 
| 2814   VisitMarker marker(info()); | 2814   VisitMarker marker(info()); | 
| 2815   int element_count = elms_->length(); | 2815   int element_count = elms_->length(); | 
| 2816   for (int i = 0; i < element_count; i++) { | 2816   for (int i = 0; i < element_count; i++) { | 
| 2817     TextElement elm = elms_->at(i); | 2817     TextElement elm = elms_->at(i); | 
| 2818     if (elm.type == TextElement::ATOM) { | 2818     if (elm.text_type == TextElement::ATOM) { | 
| 2819       Vector<const uc16> quarks = elm.data.u_atom->data(); | 2819       Vector<const uc16> quarks = elm.data.u_atom->data(); | 
| 2820       for (int j = 0; j < quarks.length(); j++) { | 2820       for (int j = 0; j < quarks.length(); j++) { | 
| 2821         uint16_t c = quarks[j]; | 2821         uint16_t c = quarks[j]; | 
| 2822         if (c <= String::kMaxOneByteCharCode) continue; | 2822         if (c <= String::kMaxOneByteCharCode) continue; | 
| 2823         if (!ignore_case) return set_replacement(NULL); | 2823         if (!ignore_case) return set_replacement(NULL); | 
| 2824         // Here, we need to check for characters whose upper and lower cases | 2824         // Here, we need to check for characters whose upper and lower cases | 
| 2825         // are outside the Latin-1 range. | 2825         // are outside the Latin-1 range. | 
| 2826         uint16_t converted = unibrow::Latin1::ConvertNonLatin1ToLatin1(c); | 2826         uint16_t converted = unibrow::Latin1::ConvertNonLatin1ToLatin1(c); | 
| 2827         // Character is outside Latin-1 completely | 2827         // Character is outside Latin-1 completely | 
| 2828         if (converted == 0) return set_replacement(NULL); | 2828         if (converted == 0) return set_replacement(NULL); | 
| 2829         // Convert quark to Latin-1 in place. | 2829         // Convert quark to Latin-1 in place. | 
| 2830         uint16_t* copy = const_cast<uint16_t*>(quarks.start()); | 2830         uint16_t* copy = const_cast<uint16_t*>(quarks.start()); | 
| 2831         copy[j] = converted; | 2831         copy[j] = converted; | 
| 2832       } | 2832       } | 
| 2833     } else { | 2833     } else { | 
| 2834       ASSERT(elm.type == TextElement::CHAR_CLASS); | 2834       ASSERT(elm.text_type == TextElement::CHAR_CLASS); | 
| 2835       RegExpCharacterClass* cc = elm.data.u_char_class; | 2835       RegExpCharacterClass* cc = elm.data.u_char_class; | 
| 2836       ZoneList<CharacterRange>* ranges = cc->ranges(zone()); | 2836       ZoneList<CharacterRange>* ranges = cc->ranges(zone()); | 
| 2837       if (!CharacterRange::IsCanonical(ranges)) { | 2837       if (!CharacterRange::IsCanonical(ranges)) { | 
| 2838         CharacterRange::Canonicalize(ranges); | 2838         CharacterRange::Canonicalize(ranges); | 
| 2839       } | 2839       } | 
| 2840       // Now they are in order so we only need to look at the first. | 2840       // Now they are in order so we only need to look at the first. | 
| 2841       int range_count = ranges->length(); | 2841       int range_count = ranges->length(); | 
| 2842       if (cc->is_negated()) { | 2842       if (cc->is_negated()) { | 
| 2843         if (range_count != 0 && | 2843         if (range_count != 0 && | 
| 2844             ranges->at(0).from() == 0 && | 2844             ranges->at(0).from() == 0 && | 
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3079       BoyerMooreLookahead* bm = | 3079       BoyerMooreLookahead* bm = | 
| 3080           new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone()); | 3080           new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone()); | 
| 3081       FillInBMInfo(0, kRecursionBudget, bm, not_at_start); | 3081       FillInBMInfo(0, kRecursionBudget, bm, not_at_start); | 
| 3082       if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; | 3082       if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; | 
| 3083       if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE; | 3083       if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE; | 
| 3084     } | 3084     } | 
| 3085   } else { | 3085   } else { | 
| 3086     if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; | 3086     if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; | 
| 3087     if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE; | 3087     if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE; | 
| 3088   } | 3088   } | 
| 3089   bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY); | 3089   bool at_boundary = (assertion_type_ == AssertionNode::AT_BOUNDARY); | 
| 3090   if (next_is_word_character == Trace::UNKNOWN) { | 3090   if (next_is_word_character == Trace::UNKNOWN) { | 
| 3091     Label before_non_word; | 3091     Label before_non_word; | 
| 3092     Label before_word; | 3092     Label before_word; | 
| 3093     if (trace->characters_preloaded() != 1) { | 3093     if (trace->characters_preloaded() != 1) { | 
| 3094       assembler->LoadCurrentCharacter(trace->cp_offset(), &before_non_word); | 3094       assembler->LoadCurrentCharacter(trace->cp_offset(), &before_non_word); | 
| 3095     } | 3095     } | 
| 3096     // Fall through on non-word. | 3096     // Fall through on non-word. | 
| 3097     EmitWordCheck(assembler, &before_word, &before_non_word, false); | 3097     EmitWordCheck(assembler, &before_word, &before_non_word, false); | 
| 3098     // Next character is not a word character. | 3098     // Next character is not a word character. | 
| 3099     assembler->Bind(&before_non_word); | 3099     assembler->Bind(&before_non_word); | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3142 | 3142 | 
| 3143   assembler->Bind(&fall_through); | 3143   assembler->Bind(&fall_through); | 
| 3144   on_success()->Emit(compiler, &new_trace); | 3144   on_success()->Emit(compiler, &new_trace); | 
| 3145 } | 3145 } | 
| 3146 | 3146 | 
| 3147 | 3147 | 
| 3148 void AssertionNode::GetQuickCheckDetails(QuickCheckDetails* details, | 3148 void AssertionNode::GetQuickCheckDetails(QuickCheckDetails* details, | 
| 3149                                          RegExpCompiler* compiler, | 3149                                          RegExpCompiler* compiler, | 
| 3150                                          int filled_in, | 3150                                          int filled_in, | 
| 3151                                          bool not_at_start) { | 3151                                          bool not_at_start) { | 
| 3152   if (type_ == AT_START && not_at_start) { | 3152   if (assertion_type_ == AT_START && not_at_start) { | 
| 3153     details->set_cannot_match(); | 3153     details->set_cannot_match(); | 
| 3154     return; | 3154     return; | 
| 3155   } | 3155   } | 
| 3156   return on_success()->GetQuickCheckDetails(details, | 3156   return on_success()->GetQuickCheckDetails(details, | 
| 3157                                             compiler, | 3157                                             compiler, | 
| 3158                                             filled_in, | 3158                                             filled_in, | 
| 3159                                             not_at_start); | 3159                                             not_at_start); | 
| 3160 } | 3160 } | 
| 3161 | 3161 | 
| 3162 | 3162 | 
| 3163 void AssertionNode::Emit(RegExpCompiler* compiler, Trace* trace) { | 3163 void AssertionNode::Emit(RegExpCompiler* compiler, Trace* trace) { | 
| 3164   RegExpMacroAssembler* assembler = compiler->macro_assembler(); | 3164   RegExpMacroAssembler* assembler = compiler->macro_assembler(); | 
| 3165   switch (type_) { | 3165   switch (assertion_type_) { | 
| 3166     case AT_END: { | 3166     case AT_END: { | 
| 3167       Label ok; | 3167       Label ok; | 
| 3168       assembler->CheckPosition(trace->cp_offset(), &ok); | 3168       assembler->CheckPosition(trace->cp_offset(), &ok); | 
| 3169       assembler->GoTo(trace->backtrack()); | 3169       assembler->GoTo(trace->backtrack()); | 
| 3170       assembler->Bind(&ok); | 3170       assembler->Bind(&ok); | 
| 3171       break; | 3171       break; | 
| 3172     } | 3172     } | 
| 3173     case AT_START: { | 3173     case AT_START: { | 
| 3174       if (trace->at_start() == Trace::FALSE) { | 3174       if (trace->at_start() == Trace::FALSE) { | 
| 3175         assembler->GoTo(trace->backtrack()); | 3175         assembler->GoTo(trace->backtrack()); | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3248                             int* checked_up_to) { | 3248                             int* checked_up_to) { | 
| 3249   Isolate* isolate = Isolate::Current(); | 3249   Isolate* isolate = Isolate::Current(); | 
| 3250   RegExpMacroAssembler* assembler = compiler->macro_assembler(); | 3250   RegExpMacroAssembler* assembler = compiler->macro_assembler(); | 
| 3251   bool ascii = compiler->ascii(); | 3251   bool ascii = compiler->ascii(); | 
| 3252   Label* backtrack = trace->backtrack(); | 3252   Label* backtrack = trace->backtrack(); | 
| 3253   QuickCheckDetails* quick_check = trace->quick_check_performed(); | 3253   QuickCheckDetails* quick_check = trace->quick_check_performed(); | 
| 3254   int element_count = elms_->length(); | 3254   int element_count = elms_->length(); | 
| 3255   for (int i = preloaded ? 0 : element_count - 1; i >= 0; i--) { | 3255   for (int i = preloaded ? 0 : element_count - 1; i >= 0; i--) { | 
| 3256     TextElement elm = elms_->at(i); | 3256     TextElement elm = elms_->at(i); | 
| 3257     int cp_offset = trace->cp_offset() + elm.cp_offset; | 3257     int cp_offset = trace->cp_offset() + elm.cp_offset; | 
| 3258     if (elm.type == TextElement::ATOM) { | 3258     if (elm.text_type == TextElement::ATOM) { | 
| 3259       Vector<const uc16> quarks = elm.data.u_atom->data(); | 3259       Vector<const uc16> quarks = elm.data.u_atom->data(); | 
| 3260       for (int j = preloaded ? 0 : quarks.length() - 1; j >= 0; j--) { | 3260       for (int j = preloaded ? 0 : quarks.length() - 1; j >= 0; j--) { | 
| 3261         if (first_element_checked && i == 0 && j == 0) continue; | 3261         if (first_element_checked && i == 0 && j == 0) continue; | 
| 3262         if (DeterminedAlready(quick_check, elm.cp_offset + j)) continue; | 3262         if (DeterminedAlready(quick_check, elm.cp_offset + j)) continue; | 
| 3263         EmitCharacterFunction* emit_function = NULL; | 3263         EmitCharacterFunction* emit_function = NULL; | 
| 3264         switch (pass) { | 3264         switch (pass) { | 
| 3265           case NON_ASCII_MATCH: | 3265           case NON_ASCII_MATCH: | 
| 3266             ASSERT(ascii); | 3266             ASSERT(ascii); | 
| 3267             if (quarks[j] > String::kMaxOneByteCharCode) { | 3267             if (quarks[j] > String::kMaxOneByteCharCode) { | 
| 3268               assembler->GoTo(backtrack); | 3268               assembler->GoTo(backtrack); | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 3286                                              compiler, | 3286                                              compiler, | 
| 3287                                              quarks[j], | 3287                                              quarks[j], | 
| 3288                                              backtrack, | 3288                                              backtrack, | 
| 3289                                              cp_offset + j, | 3289                                              cp_offset + j, | 
| 3290                                              *checked_up_to < cp_offset + j, | 3290                                              *checked_up_to < cp_offset + j, | 
| 3291                                              preloaded); | 3291                                              preloaded); | 
| 3292           if (bound_checked) UpdateBoundsCheck(cp_offset + j, checked_up_to); | 3292           if (bound_checked) UpdateBoundsCheck(cp_offset + j, checked_up_to); | 
| 3293         } | 3293         } | 
| 3294       } | 3294       } | 
| 3295     } else { | 3295     } else { | 
| 3296       ASSERT_EQ(elm.type, TextElement::CHAR_CLASS); | 3296       ASSERT_EQ(elm.text_type, TextElement::CHAR_CLASS); | 
| 3297       if (pass == CHARACTER_CLASS_MATCH) { | 3297       if (pass == CHARACTER_CLASS_MATCH) { | 
| 3298         if (first_element_checked && i == 0) continue; | 3298         if (first_element_checked && i == 0) continue; | 
| 3299         if (DeterminedAlready(quick_check, elm.cp_offset)) continue; | 3299         if (DeterminedAlready(quick_check, elm.cp_offset)) continue; | 
| 3300         RegExpCharacterClass* cc = elm.data.u_char_class; | 3300         RegExpCharacterClass* cc = elm.data.u_char_class; | 
| 3301         EmitCharClass(assembler, | 3301         EmitCharClass(assembler, | 
| 3302                       cc, | 3302                       cc, | 
| 3303                       ascii, | 3303                       ascii, | 
| 3304                       backtrack, | 3304                       backtrack, | 
| 3305                       cp_offset, | 3305                       cp_offset, | 
| 3306                       *checked_up_to < cp_offset, | 3306                       *checked_up_to < cp_offset, | 
| 3307                       preloaded, | 3307                       preloaded, | 
| 3308                       zone()); | 3308                       zone()); | 
| 3309         UpdateBoundsCheck(cp_offset, checked_up_to); | 3309         UpdateBoundsCheck(cp_offset, checked_up_to); | 
| 3310       } | 3310       } | 
| 3311     } | 3311     } | 
| 3312   } | 3312   } | 
| 3313 } | 3313 } | 
| 3314 | 3314 | 
| 3315 | 3315 | 
| 3316 int TextNode::Length() { | 3316 int TextNode::Length() { | 
| 3317   TextElement elm = elms_->last(); | 3317   TextElement elm = elms_->last(); | 
| 3318   ASSERT(elm.cp_offset >= 0); | 3318   ASSERT(elm.cp_offset >= 0); | 
| 3319   if (elm.type == TextElement::ATOM) { | 3319   if (elm.text_type == TextElement::ATOM) { | 
| 3320     return elm.cp_offset + elm.data.u_atom->data().length(); | 3320     return elm.cp_offset + elm.data.u_atom->data().length(); | 
| 3321   } else { | 3321   } else { | 
| 3322     return elm.cp_offset + 1; | 3322     return elm.cp_offset + 1; | 
| 3323   } | 3323   } | 
| 3324 } | 3324 } | 
| 3325 | 3325 | 
| 3326 | 3326 | 
| 3327 bool TextNode::SkipPass(int int_pass, bool ignore_case) { | 3327 bool TextNode::SkipPass(int int_pass, bool ignore_case) { | 
| 3328   TextEmitPassType pass = static_cast<TextEmitPassType>(int_pass); | 3328   TextEmitPassType pass = static_cast<TextEmitPassType>(int_pass); | 
| 3329   if (ignore_case) { | 3329   if (ignore_case) { | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3415     cp_offset_ = 0; | 3415     cp_offset_ = 0; | 
| 3416   } | 3416   } | 
| 3417   bound_checked_up_to_ = Max(0, bound_checked_up_to_ - by); | 3417   bound_checked_up_to_ = Max(0, bound_checked_up_to_ - by); | 
| 3418 } | 3418 } | 
| 3419 | 3419 | 
| 3420 | 3420 | 
| 3421 void TextNode::MakeCaseIndependent(bool is_ascii) { | 3421 void TextNode::MakeCaseIndependent(bool is_ascii) { | 
| 3422   int element_count = elms_->length(); | 3422   int element_count = elms_->length(); | 
| 3423   for (int i = 0; i < element_count; i++) { | 3423   for (int i = 0; i < element_count; i++) { | 
| 3424     TextElement elm = elms_->at(i); | 3424     TextElement elm = elms_->at(i); | 
| 3425     if (elm.type == TextElement::CHAR_CLASS) { | 3425     if (elm.text_type == TextElement::CHAR_CLASS) { | 
| 3426       RegExpCharacterClass* cc = elm.data.u_char_class; | 3426       RegExpCharacterClass* cc = elm.data.u_char_class; | 
| 3427       // None of the standard character classes is different in the case | 3427       // None of the standard character classes is different in the case | 
| 3428       // independent case and it slows us down if we don't know that. | 3428       // independent case and it slows us down if we don't know that. | 
| 3429       if (cc->is_standard(zone())) continue; | 3429       if (cc->is_standard(zone())) continue; | 
| 3430       ZoneList<CharacterRange>* ranges = cc->ranges(zone()); | 3430       ZoneList<CharacterRange>* ranges = cc->ranges(zone()); | 
| 3431       int range_count = ranges->length(); | 3431       int range_count = ranges->length(); | 
| 3432       for (int j = 0; j < range_count; j++) { | 3432       for (int j = 0; j < range_count; j++) { | 
| 3433         ranges->at(j).AddCaseEquivalents(ranges, is_ascii, zone()); | 3433         ranges->at(j).AddCaseEquivalents(ranges, is_ascii, zone()); | 
| 3434       } | 3434       } | 
| 3435     } | 3435     } | 
| 3436   } | 3436   } | 
| 3437 } | 3437 } | 
| 3438 | 3438 | 
| 3439 | 3439 | 
| 3440 int TextNode::GreedyLoopTextLength() { | 3440 int TextNode::GreedyLoopTextLength() { | 
| 3441   TextElement elm = elms_->at(elms_->length() - 1); | 3441   TextElement elm = elms_->at(elms_->length() - 1); | 
| 3442   if (elm.type == TextElement::CHAR_CLASS) { | 3442   if (elm.text_type == TextElement::CHAR_CLASS) { | 
| 3443     return elm.cp_offset + 1; | 3443     return elm.cp_offset + 1; | 
| 3444   } else { | 3444   } else { | 
| 3445     return elm.cp_offset + elm.data.u_atom->data().length(); | 3445     return elm.cp_offset + elm.data.u_atom->data().length(); | 
| 3446   } | 3446   } | 
| 3447 } | 3447 } | 
| 3448 | 3448 | 
| 3449 | 3449 | 
| 3450 RegExpNode* TextNode::GetSuccessorOfOmnivorousTextNode( | 3450 RegExpNode* TextNode::GetSuccessorOfOmnivorousTextNode( | 
| 3451     RegExpCompiler* compiler) { | 3451     RegExpCompiler* compiler) { | 
| 3452   if (elms_->length() != 1) return NULL; | 3452   if (elms_->length() != 1) return NULL; | 
| 3453   TextElement elm = elms_->at(0); | 3453   TextElement elm = elms_->at(0); | 
| 3454   if (elm.type != TextElement::CHAR_CLASS) return NULL; | 3454   if (elm.text_type != TextElement::CHAR_CLASS) return NULL; | 
| 3455   RegExpCharacterClass* node = elm.data.u_char_class; | 3455   RegExpCharacterClass* node = elm.data.u_char_class; | 
| 3456   ZoneList<CharacterRange>* ranges = node->ranges(zone()); | 3456   ZoneList<CharacterRange>* ranges = node->ranges(zone()); | 
| 3457   if (!CharacterRange::IsCanonical(ranges)) { | 3457   if (!CharacterRange::IsCanonical(ranges)) { | 
| 3458     CharacterRange::Canonicalize(ranges); | 3458     CharacterRange::Canonicalize(ranges); | 
| 3459   } | 3459   } | 
| 3460   if (node->is_negated()) { | 3460   if (node->is_negated()) { | 
| 3461     return ranges->length() == 0 ? on_success() : NULL; | 3461     return ranges->length() == 0 ? on_success() : NULL; | 
| 3462   } | 3462   } | 
| 3463   if (ranges->length() != 1) return NULL; | 3463   if (ranges->length() != 1) return NULL; | 
| 3464   uint32_t max_char; | 3464   uint32_t max_char; | 
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4189 | 4189 | 
| 4190 | 4190 | 
| 4191 void ActionNode::Emit(RegExpCompiler* compiler, Trace* trace) { | 4191 void ActionNode::Emit(RegExpCompiler* compiler, Trace* trace) { | 
| 4192   RegExpMacroAssembler* assembler = compiler->macro_assembler(); | 4192   RegExpMacroAssembler* assembler = compiler->macro_assembler(); | 
| 4193   LimitResult limit_result = LimitVersions(compiler, trace); | 4193   LimitResult limit_result = LimitVersions(compiler, trace); | 
| 4194   if (limit_result == DONE) return; | 4194   if (limit_result == DONE) return; | 
| 4195   ASSERT(limit_result == CONTINUE); | 4195   ASSERT(limit_result == CONTINUE); | 
| 4196 | 4196 | 
| 4197   RecursionCheck rc(compiler); | 4197   RecursionCheck rc(compiler); | 
| 4198 | 4198 | 
| 4199   switch (type_) { | 4199   switch (action_type_) { | 
| 4200     case STORE_POSITION: { | 4200     case STORE_POSITION: { | 
| 4201       Trace::DeferredCapture | 4201       Trace::DeferredCapture | 
| 4202           new_capture(data_.u_position_register.reg, | 4202           new_capture(data_.u_position_register.reg, | 
| 4203                       data_.u_position_register.is_capture, | 4203                       data_.u_position_register.is_capture, | 
| 4204                       trace); | 4204                       trace); | 
| 4205       Trace new_trace = *trace; | 4205       Trace new_trace = *trace; | 
| 4206       new_trace.add_action(&new_capture); | 4206       new_trace.add_action(&new_capture); | 
| 4207       on_success()->Emit(compiler, &new_trace); | 4207       on_success()->Emit(compiler, &new_trace); | 
| 4208       break; | 4208       break; | 
| 4209     } | 4209     } | 
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4519   } | 4519   } | 
| 4520 } | 4520 } | 
| 4521 | 4521 | 
| 4522 | 4522 | 
| 4523 void DotPrinter::VisitText(TextNode* that) { | 4523 void DotPrinter::VisitText(TextNode* that) { | 
| 4524   Zone* zone = that->zone(); | 4524   Zone* zone = that->zone(); | 
| 4525   stream()->Add("  n%p [label=\"", that); | 4525   stream()->Add("  n%p [label=\"", that); | 
| 4526   for (int i = 0; i < that->elements()->length(); i++) { | 4526   for (int i = 0; i < that->elements()->length(); i++) { | 
| 4527     if (i > 0) stream()->Add(" "); | 4527     if (i > 0) stream()->Add(" "); | 
| 4528     TextElement elm = that->elements()->at(i); | 4528     TextElement elm = that->elements()->at(i); | 
| 4529     switch (elm.type) { | 4529     switch (elm.text_type) { | 
| 4530       case TextElement::ATOM: { | 4530       case TextElement::ATOM: { | 
| 4531         stream()->Add("'%w'", elm.data.u_atom->data()); | 4531         stream()->Add("'%w'", elm.data.u_atom->data()); | 
| 4532         break; | 4532         break; | 
| 4533       } | 4533       } | 
| 4534       case TextElement::CHAR_CLASS: { | 4534       case TextElement::CHAR_CLASS: { | 
| 4535         RegExpCharacterClass* node = elm.data.u_char_class; | 4535         RegExpCharacterClass* node = elm.data.u_char_class; | 
| 4536         stream()->Add("["); | 4536         stream()->Add("["); | 
| 4537         if (node->is_negated()) | 4537         if (node->is_negated()) | 
| 4538           stream()->Add("^"); | 4538           stream()->Add("^"); | 
| 4539         for (int j = 0; j < node->ranges(zone)->length(); j++) { | 4539         for (int j = 0; j < node->ranges(zone)->length(); j++) { | 
| (...skipping 26 matching lines...) Expand all  Loading... | 
| 4566 | 4566 | 
| 4567 | 4567 | 
| 4568 void DotPrinter::VisitEnd(EndNode* that) { | 4568 void DotPrinter::VisitEnd(EndNode* that) { | 
| 4569   stream()->Add("  n%p [style=bold, shape=point];\n", that); | 4569   stream()->Add("  n%p [style=bold, shape=point];\n", that); | 
| 4570   PrintAttributes(that); | 4570   PrintAttributes(that); | 
| 4571 } | 4571 } | 
| 4572 | 4572 | 
| 4573 | 4573 | 
| 4574 void DotPrinter::VisitAssertion(AssertionNode* that) { | 4574 void DotPrinter::VisitAssertion(AssertionNode* that) { | 
| 4575   stream()->Add("  n%p [", that); | 4575   stream()->Add("  n%p [", that); | 
| 4576   switch (that->type()) { | 4576   switch (that->assertion_type()) { | 
| 4577     case AssertionNode::AT_END: | 4577     case AssertionNode::AT_END: | 
| 4578       stream()->Add("label=\"$\", shape=septagon"); | 4578       stream()->Add("label=\"$\", shape=septagon"); | 
| 4579       break; | 4579       break; | 
| 4580     case AssertionNode::AT_START: | 4580     case AssertionNode::AT_START: | 
| 4581       stream()->Add("label=\"^\", shape=septagon"); | 4581       stream()->Add("label=\"^\", shape=septagon"); | 
| 4582       break; | 4582       break; | 
| 4583     case AssertionNode::AT_BOUNDARY: | 4583     case AssertionNode::AT_BOUNDARY: | 
| 4584       stream()->Add("label=\"\\b\", shape=septagon"); | 4584       stream()->Add("label=\"\\b\", shape=septagon"); | 
| 4585       break; | 4585       break; | 
| 4586     case AssertionNode::AT_NON_BOUNDARY: | 4586     case AssertionNode::AT_NON_BOUNDARY: | 
| 4587       stream()->Add("label=\"\\B\", shape=septagon"); | 4587       stream()->Add("label=\"\\B\", shape=septagon"); | 
| 4588       break; | 4588       break; | 
| 4589     case AssertionNode::AFTER_NEWLINE: | 4589     case AssertionNode::AFTER_NEWLINE: | 
| 4590       stream()->Add("label=\"(?<=\\n)\", shape=septagon"); | 4590       stream()->Add("label=\"(?<=\\n)\", shape=septagon"); | 
| 4591       break; | 4591       break; | 
| 4592   } | 4592   } | 
| 4593   stream()->Add("];\n"); | 4593   stream()->Add("];\n"); | 
| 4594   PrintAttributes(that); | 4594   PrintAttributes(that); | 
| 4595   RegExpNode* successor = that->on_success(); | 4595   RegExpNode* successor = that->on_success(); | 
| 4596   stream()->Add("  n%p -> n%p;\n", that, successor); | 4596   stream()->Add("  n%p -> n%p;\n", that, successor); | 
| 4597   Visit(successor); | 4597   Visit(successor); | 
| 4598 } | 4598 } | 
| 4599 | 4599 | 
| 4600 | 4600 | 
| 4601 void DotPrinter::VisitAction(ActionNode* that) { | 4601 void DotPrinter::VisitAction(ActionNode* that) { | 
| 4602   stream()->Add("  n%p [", that); | 4602   stream()->Add("  n%p [", that); | 
| 4603   switch (that->type_) { | 4603   switch (that->action_type_) { | 
| 4604     case ActionNode::SET_REGISTER: | 4604     case ActionNode::SET_REGISTER: | 
| 4605       stream()->Add("label=\"$%i:=%i\", shape=octagon", | 4605       stream()->Add("label=\"$%i:=%i\", shape=octagon", | 
| 4606                     that->data_.u_store_register.reg, | 4606                     that->data_.u_store_register.reg, | 
| 4607                     that->data_.u_store_register.value); | 4607                     that->data_.u_store_register.value); | 
| 4608       break; | 4608       break; | 
| 4609     case ActionNode::INCREMENT_REGISTER: | 4609     case ActionNode::INCREMENT_REGISTER: | 
| 4610       stream()->Add("label=\"$%i++\", shape=octagon", | 4610       stream()->Add("label=\"$%i++\", shape=octagon", | 
| 4611                     that->data_.u_increment_register.reg); | 4611                     that->data_.u_increment_register.reg); | 
| 4612       break; | 4612       break; | 
| 4613     case ActionNode::STORE_POSITION: | 4613     case ActionNode::STORE_POSITION: | 
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5006     return center; | 5006     return center; | 
| 5007   } | 5007   } | 
| 5008 } | 5008 } | 
| 5009 | 5009 | 
| 5010 | 5010 | 
| 5011 RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler, | 5011 RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler, | 
| 5012                                     RegExpNode* on_success) { | 5012                                     RegExpNode* on_success) { | 
| 5013   NodeInfo info; | 5013   NodeInfo info; | 
| 5014   Zone* zone = compiler->zone(); | 5014   Zone* zone = compiler->zone(); | 
| 5015 | 5015 | 
| 5016   switch (type()) { | 5016   switch (assertion_type()) { | 
| 5017     case START_OF_LINE: | 5017     case START_OF_LINE: | 
| 5018       return AssertionNode::AfterNewline(on_success); | 5018       return AssertionNode::AfterNewline(on_success); | 
| 5019     case START_OF_INPUT: | 5019     case START_OF_INPUT: | 
| 5020       return AssertionNode::AtStart(on_success); | 5020       return AssertionNode::AtStart(on_success); | 
| 5021     case BOUNDARY: | 5021     case BOUNDARY: | 
| 5022       return AssertionNode::AtBoundary(on_success); | 5022       return AssertionNode::AtBoundary(on_success); | 
| 5023     case NON_BOUNDARY: | 5023     case NON_BOUNDARY: | 
| 5024       return AssertionNode::AtNonBoundary(on_success); | 5024       return AssertionNode::AtNonBoundary(on_success); | 
| 5025     case END_OF_INPUT: | 5025     case END_OF_INPUT: | 
| 5026       return AssertionNode::AtEnd(on_success); | 5026       return AssertionNode::AtEnd(on_success); | 
| (...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5708 | 5708 | 
| 5709 | 5709 | 
| 5710 void TextNode::CalculateOffsets() { | 5710 void TextNode::CalculateOffsets() { | 
| 5711   int element_count = elements()->length(); | 5711   int element_count = elements()->length(); | 
| 5712   // Set up the offsets of the elements relative to the start.  This is a fixed | 5712   // Set up the offsets of the elements relative to the start.  This is a fixed | 
| 5713   // quantity since a TextNode can only contain fixed-width things. | 5713   // quantity since a TextNode can only contain fixed-width things. | 
| 5714   int cp_offset = 0; | 5714   int cp_offset = 0; | 
| 5715   for (int i = 0; i < element_count; i++) { | 5715   for (int i = 0; i < element_count; i++) { | 
| 5716     TextElement& elm = elements()->at(i); | 5716     TextElement& elm = elements()->at(i); | 
| 5717     elm.cp_offset = cp_offset; | 5717     elm.cp_offset = cp_offset; | 
| 5718     if (elm.type == TextElement::ATOM) { | 5718     if (elm.text_type == TextElement::ATOM) { | 
| 5719       cp_offset += elm.data.u_atom->data().length(); | 5719       cp_offset += elm.data.u_atom->data().length(); | 
| 5720     } else { | 5720     } else { | 
| 5721       cp_offset++; | 5721       cp_offset++; | 
| 5722     } | 5722     } | 
| 5723   } | 5723   } | 
| 5724 } | 5724 } | 
| 5725 | 5725 | 
| 5726 | 5726 | 
| 5727 void Analysis::VisitText(TextNode* that) { | 5727 void Analysis::VisitText(TextNode* that) { | 
| 5728   if (ignore_case_) { | 5728   if (ignore_case_) { | 
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5828                             bool not_at_start) { | 5828                             bool not_at_start) { | 
| 5829   if (initial_offset >= bm->length()) return; | 5829   if (initial_offset >= bm->length()) return; | 
| 5830   int offset = initial_offset; | 5830   int offset = initial_offset; | 
| 5831   int max_char = bm->max_char(); | 5831   int max_char = bm->max_char(); | 
| 5832   for (int i = 0; i < elements()->length(); i++) { | 5832   for (int i = 0; i < elements()->length(); i++) { | 
| 5833     if (offset >= bm->length()) { | 5833     if (offset >= bm->length()) { | 
| 5834       if (initial_offset == 0) set_bm_info(not_at_start, bm); | 5834       if (initial_offset == 0) set_bm_info(not_at_start, bm); | 
| 5835       return; | 5835       return; | 
| 5836     } | 5836     } | 
| 5837     TextElement text = elements()->at(i); | 5837     TextElement text = elements()->at(i); | 
| 5838     if (text.type == TextElement::ATOM) { | 5838     if (text.text_type == TextElement::ATOM) { | 
| 5839       RegExpAtom* atom = text.data.u_atom; | 5839       RegExpAtom* atom = text.data.u_atom; | 
| 5840       for (int j = 0; j < atom->length(); j++, offset++) { | 5840       for (int j = 0; j < atom->length(); j++, offset++) { | 
| 5841         if (offset >= bm->length()) { | 5841         if (offset >= bm->length()) { | 
| 5842           if (initial_offset == 0) set_bm_info(not_at_start, bm); | 5842           if (initial_offset == 0) set_bm_info(not_at_start, bm); | 
| 5843           return; | 5843           return; | 
| 5844         } | 5844         } | 
| 5845         uc16 character = atom->data()[j]; | 5845         uc16 character = atom->data()[j]; | 
| 5846         if (bm->compiler()->ignore_case()) { | 5846         if (bm->compiler()->ignore_case()) { | 
| 5847           unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth]; | 5847           unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth]; | 
| 5848           int length = GetCaseIndependentLetters( | 5848           int length = GetCaseIndependentLetters( | 
| 5849               ISOLATE, | 5849               ISOLATE, | 
| 5850               character, | 5850               character, | 
| 5851               bm->max_char() == String::kMaxOneByteCharCode, | 5851               bm->max_char() == String::kMaxOneByteCharCode, | 
| 5852               chars); | 5852               chars); | 
| 5853           for (int j = 0; j < length; j++) { | 5853           for (int j = 0; j < length; j++) { | 
| 5854             bm->Set(offset, chars[j]); | 5854             bm->Set(offset, chars[j]); | 
| 5855           } | 5855           } | 
| 5856         } else { | 5856         } else { | 
| 5857           if (character <= max_char) bm->Set(offset, character); | 5857           if (character <= max_char) bm->Set(offset, character); | 
| 5858         } | 5858         } | 
| 5859       } | 5859       } | 
| 5860     } else { | 5860     } else { | 
| 5861       ASSERT(text.type == TextElement::CHAR_CLASS); | 5861       ASSERT(text.text_type == TextElement::CHAR_CLASS); | 
| 5862       RegExpCharacterClass* char_class = text.data.u_char_class; | 5862       RegExpCharacterClass* char_class = text.data.u_char_class; | 
| 5863       ZoneList<CharacterRange>* ranges = char_class->ranges(zone()); | 5863       ZoneList<CharacterRange>* ranges = char_class->ranges(zone()); | 
| 5864       if (char_class->is_negated()) { | 5864       if (char_class->is_negated()) { | 
| 5865         bm->SetAll(offset); | 5865         bm->SetAll(offset); | 
| 5866       } else { | 5866       } else { | 
| 5867         for (int k = 0; k < ranges->length(); k++) { | 5867         for (int k = 0; k < ranges->length(); k++) { | 
| 5868           CharacterRange& range = ranges->at(k); | 5868           CharacterRange& range = ranges->at(k); | 
| 5869           if (range.from() > max_char) continue; | 5869           if (range.from() > max_char) continue; | 
| 5870           int to = Min(max_char, static_cast<int>(range.to())); | 5870           int to = Min(max_char, static_cast<int>(range.to())); | 
| 5871           bm->SetInterval(offset, Interval(range.from(), to)); | 5871           bm->SetInterval(offset, Interval(range.from(), to)); | 
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 5964         last = range.to() + 1; | 5964         last = range.to() + 1; | 
| 5965       } | 5965       } | 
| 5966     } | 5966     } | 
| 5967   } | 5967   } | 
| 5968   AddRange(CharacterRange(last, String::kMaxUtf16CodeUnit)); | 5968   AddRange(CharacterRange(last, String::kMaxUtf16CodeUnit)); | 
| 5969 } | 5969 } | 
| 5970 | 5970 | 
| 5971 | 5971 | 
| 5972 void DispatchTableConstructor::VisitText(TextNode* that) { | 5972 void DispatchTableConstructor::VisitText(TextNode* that) { | 
| 5973   TextElement elm = that->elements()->at(0); | 5973   TextElement elm = that->elements()->at(0); | 
| 5974   switch (elm.type) { | 5974   switch (elm.text_type) { | 
| 5975     case TextElement::ATOM: { | 5975     case TextElement::ATOM: { | 
| 5976       uc16 c = elm.data.u_atom->data()[0]; | 5976       uc16 c = elm.data.u_atom->data()[0]; | 
| 5977       AddRange(CharacterRange(c, c)); | 5977       AddRange(CharacterRange(c, c)); | 
| 5978       break; | 5978       break; | 
| 5979     } | 5979     } | 
| 5980     case TextElement::CHAR_CLASS: { | 5980     case TextElement::CHAR_CLASS: { | 
| 5981       RegExpCharacterClass* tree = elm.data.u_char_class; | 5981       RegExpCharacterClass* tree = elm.data.u_char_class; | 
| 5982       ZoneList<CharacterRange>* ranges = tree->ranges(that->zone()); | 5982       ZoneList<CharacterRange>* ranges = tree->ranges(that->zone()); | 
| 5983       if (tree->is_negated()) { | 5983       if (tree->is_negated()) { | 
| 5984         AddInverse(ranges); | 5984         AddInverse(ranges); | 
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 6123   } | 6123   } | 
| 6124 | 6124 | 
| 6125   return compiler.Assemble(¯o_assembler, | 6125   return compiler.Assemble(¯o_assembler, | 
| 6126                            node, | 6126                            node, | 
| 6127                            data->capture_count, | 6127                            data->capture_count, | 
| 6128                            pattern); | 6128                            pattern); | 
| 6129 } | 6129 } | 
| 6130 | 6130 | 
| 6131 | 6131 | 
| 6132 }}  // namespace v8::internal | 6132 }}  // namespace v8::internal | 
| OLD | NEW | 
|---|