OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2419 char_mask = String::kMaxUtf16CodeUnit; | 2419 char_mask = String::kMaxUtf16CodeUnit; |
2420 } | 2420 } |
2421 for (int k = 0; k < elms_->length(); k++) { | 2421 for (int k = 0; k < elms_->length(); k++) { |
2422 TextElement elm = elms_->at(k); | 2422 TextElement elm = elms_->at(k); |
2423 if (elm.type == TextElement::ATOM) { | 2423 if (elm.type == TextElement::ATOM) { |
2424 Vector<const uc16> quarks = elm.data.u_atom->data(); | 2424 Vector<const uc16> quarks = elm.data.u_atom->data(); |
2425 for (int i = 0; i < characters && i < quarks.length(); i++) { | 2425 for (int i = 0; i < characters && i < quarks.length(); i++) { |
2426 QuickCheckDetails::Position* pos = | 2426 QuickCheckDetails::Position* pos = |
2427 details->positions(characters_filled_in); | 2427 details->positions(characters_filled_in); |
2428 uc16 c = quarks[i]; | 2428 uc16 c = quarks[i]; |
2429 // We should already have filtered out nodes that have non-ASCII | 2429 if (c > char_mask) { |
2430 // characters if we are matching against an ASCII string. | 2430 // If we expect a non-ASCII character from an ASCII string, |
2431 ASSERT(c <= char_mask); | 2431 // there is no way we can match. Not even case independent |
2432 // matching can turn an ASCII character into non-ASCII or» | |
ulan
2012/05/03 08:18:45
Tabs and trailing spaces in this block.
| |
2433 // vice versa.» | |
2434 details->set_cannot_match();» | |
2435 pos->determines_perfectly = false;» | |
2436 return;» | |
2437 } | |
2432 if (compiler->ignore_case()) { | 2438 if (compiler->ignore_case()) { |
2433 unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth]; | 2439 unibrow::uchar chars[unibrow::Ecma262UnCanonicalize::kMaxWidth]; |
2434 int length = GetCaseIndependentLetters(isolate, c, compiler->ascii(), | 2440 int length = GetCaseIndependentLetters(isolate, c, compiler->ascii(), |
2435 chars); | 2441 chars); |
2436 ASSERT(length != 0); // Can only happen if c > char_mask (see above). | 2442 ASSERT(length != 0); // Can only happen if c > char_mask (see above). |
2437 if (length == 1) { | 2443 if (length == 1) { |
2438 // This letter has no case equivalents, so it's nice and simple | 2444 // This letter has no case equivalents, so it's nice and simple |
2439 // and the mask-compare will determine definitely whether we have | 2445 // and the mask-compare will determine definitely whether we have |
2440 // a match at this character position. | 2446 // a match at this character position. |
2441 pos->mask = char_mask; | 2447 pos->mask = char_mask; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2483 // A quick check uses multi-character mask and compare. There is no | 2489 // A quick check uses multi-character mask and compare. There is no |
2484 // useful way to incorporate a negative char class into this scheme | 2490 // useful way to incorporate a negative char class into this scheme |
2485 // so we just conservatively create a mask and value that will always | 2491 // so we just conservatively create a mask and value that will always |
2486 // succeed. | 2492 // succeed. |
2487 pos->mask = 0; | 2493 pos->mask = 0; |
2488 pos->value = 0; | 2494 pos->value = 0; |
2489 } else { | 2495 } else { |
2490 int first_range = 0; | 2496 int first_range = 0; |
2491 while (ranges->at(first_range).from() > char_mask) { | 2497 while (ranges->at(first_range).from() > char_mask) { |
2492 first_range++; | 2498 first_range++; |
2493 // We should already have filtered out nodes that cannot match | 2499 if (first_range == ranges->length()) { |
2494 // so the first range should be a valid range. | 2500 details->set_cannot_match(); |
2495 ASSERT(first_range != ranges->length()); | 2501 pos->determines_perfectly = false; |
2502 return; | |
2503 } | |
2496 } | 2504 } |
2497 CharacterRange range = ranges->at(first_range); | 2505 CharacterRange range = ranges->at(first_range); |
2498 uc16 from = range.from(); | 2506 uc16 from = range.from(); |
2499 uc16 to = range.to(); | 2507 uc16 to = range.to(); |
2500 if (to > char_mask) { | 2508 if (to > char_mask) { |
2501 to = char_mask; | 2509 to = char_mask; |
2502 } | 2510 } |
2503 uint32_t differing_bits = (from ^ to); | 2511 uint32_t differing_bits = (from ^ to); |
2504 // A mask and compare is only perfect if the differing bits form a | 2512 // A mask and compare is only perfect if the differing bits form a |
2505 // number like 00011111 with one single block of trailing 1s. | 2513 // number like 00011111 with one single block of trailing 1s. |
(...skipping 27 matching lines...) Expand all Loading... | |
2533 pos->value = bits; | 2541 pos->value = bits; |
2534 } | 2542 } |
2535 characters_filled_in++; | 2543 characters_filled_in++; |
2536 ASSERT(characters_filled_in <= details->characters()); | 2544 ASSERT(characters_filled_in <= details->characters()); |
2537 if (characters_filled_in == details->characters()) { | 2545 if (characters_filled_in == details->characters()) { |
2538 return; | 2546 return; |
2539 } | 2547 } |
2540 } | 2548 } |
2541 } | 2549 } |
2542 ASSERT(characters_filled_in != details->characters()); | 2550 ASSERT(characters_filled_in != details->characters()); |
2543 on_success()-> GetQuickCheckDetails(details, | 2551 if (!details->cannot_match()) { |
2544 compiler, | 2552 on_success()-> GetQuickCheckDetails(details, |
2545 characters_filled_in, | 2553 compiler, |
2546 true); | 2554 characters_filled_in, |
2555 true); | |
2556 } | |
2547 } | 2557 } |
2548 | 2558 |
2549 | 2559 |
2550 void QuickCheckDetails::Clear() { | 2560 void QuickCheckDetails::Clear() { |
2551 for (int i = 0; i < characters_; i++) { | 2561 for (int i = 0; i < characters_; i++) { |
2552 positions_[i].mask = 0; | 2562 positions_[i].mask = 0; |
2553 positions_[i].value = 0; | 2563 positions_[i].value = 0; |
2554 positions_[i].determines_perfectly = false; | 2564 positions_[i].determines_perfectly = false; |
2555 } | 2565 } |
2556 characters_ = 0; | 2566 characters_ = 0; |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2680 } | 2690 } |
2681 } | 2691 } |
2682 return FilterSuccessor(depth - 1); | 2692 return FilterSuccessor(depth - 1); |
2683 } | 2693 } |
2684 | 2694 |
2685 | 2695 |
2686 RegExpNode* LoopChoiceNode::FilterASCII(int depth) { | 2696 RegExpNode* LoopChoiceNode::FilterASCII(int depth) { |
2687 if (info()->replacement_calculated) return replacement(); | 2697 if (info()->replacement_calculated) return replacement(); |
2688 if (depth < 0) return this; | 2698 if (depth < 0) return this; |
2689 if (info()->visited) return this; | 2699 if (info()->visited) return this; |
2690 VisitMarker marker(info()); | 2700 { |
2691 | 2701 VisitMarker marker(info()); |
2692 RegExpNode* continue_replacement = continue_node_->FilterASCII(depth - 1); | 2702 |
2693 // If we can't continue after the loop then there is no sense in doing the | 2703 RegExpNode* continue_replacement = continue_node_->FilterASCII(depth - 1); |
2694 // loop. | 2704 // If we can't continue after the loop then there is no sense in doing the |
2695 if (continue_replacement == NULL) return set_replacement(NULL); | 2705 // loop. |
2706 if (continue_replacement == NULL) return set_replacement(NULL); | |
2707 } | |
2696 | 2708 |
2697 return ChoiceNode::FilterASCII(depth - 1); | 2709 return ChoiceNode::FilterASCII(depth - 1); |
2698 } | 2710 } |
2699 | 2711 |
2700 | 2712 |
2701 RegExpNode* ChoiceNode::FilterASCII(int depth) { | 2713 RegExpNode* ChoiceNode::FilterASCII(int depth) { |
2702 if (info()->replacement_calculated) return replacement(); | 2714 if (info()->replacement_calculated) return replacement(); |
2703 if (depth < 0) return this; | 2715 if (depth < 0) return this; |
2704 if (info()->visited) return this; | 2716 if (info()->visited) return this; |
2705 VisitMarker marker(info()); | 2717 VisitMarker marker(info()); |
(...skipping 3159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5865 } | 5877 } |
5866 | 5878 |
5867 return compiler.Assemble(¯o_assembler, | 5879 return compiler.Assemble(¯o_assembler, |
5868 node, | 5880 node, |
5869 data->capture_count, | 5881 data->capture_count, |
5870 pattern); | 5882 pattern); |
5871 } | 5883 } |
5872 | 5884 |
5873 | 5885 |
5874 }} // namespace v8::internal | 5886 }} // namespace v8::internal |
OLD | NEW |