Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 1578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1589 | 1589 |
| 1590 | 1590 |
| 1591 #define DEFINE_ACCEPT(Type) \ | 1591 #define DEFINE_ACCEPT(Type) \ |
| 1592 void Type##Node::Accept(NodeVisitor* visitor) { \ | 1592 void Type##Node::Accept(NodeVisitor* visitor) { \ |
| 1593 visitor->Visit##Type(this); \ | 1593 visitor->Visit##Type(this); \ |
| 1594 } | 1594 } |
| 1595 FOR_EACH_NODE_TYPE(DEFINE_ACCEPT) | 1595 FOR_EACH_NODE_TYPE(DEFINE_ACCEPT) |
| 1596 #undef DEFINE_ACCEPT | 1596 #undef DEFINE_ACCEPT |
| 1597 | 1597 |
| 1598 | 1598 |
| 1599 void LoopChoiceNode::Accept(NodeVisitor* visitor) { | |
| 1600 visitor->VisitLoopChoice(this); | |
| 1601 } | |
| 1602 | |
| 1603 | |
| 1599 // ------------------------------------------------------------------- | 1604 // ------------------------------------------------------------------- |
| 1600 // Emit code. | 1605 // Emit code. |
| 1601 | 1606 |
| 1602 | 1607 |
| 1603 void ChoiceNode::GenerateGuard(RegExpMacroAssembler* macro_assembler, | 1608 void ChoiceNode::GenerateGuard(RegExpMacroAssembler* macro_assembler, |
| 1604 Guard* guard, | 1609 Guard* guard, |
| 1605 GenerationVariant* variant) { | 1610 GenerationVariant* variant) { |
| 1606 switch (guard->op()) { | 1611 switch (guard->op()) { |
| 1607 case Guard::LT: | 1612 case Guard::LT: |
| 1608 ASSERT(!variant->mentions_reg(guard->reg())); | 1613 ASSERT(!variant->mentions_reg(guard->reg())); |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2063 return kNodeIsTooComplexForGreedyLoops; | 2068 return kNodeIsTooComplexForGreedyLoops; |
| 2064 } | 2069 } |
| 2065 length += node_length; | 2070 length += node_length; |
| 2066 SeqRegExpNode* seq_node = static_cast<SeqRegExpNode*>(node); | 2071 SeqRegExpNode* seq_node = static_cast<SeqRegExpNode*>(node); |
| 2067 node = seq_node->on_success(); | 2072 node = seq_node->on_success(); |
| 2068 } | 2073 } |
| 2069 return length; | 2074 return length; |
| 2070 } | 2075 } |
| 2071 | 2076 |
| 2072 | 2077 |
| 2078 void LoopChoiceNode::AddLoopAlternative(GuardedAlternative alt) { | |
| 2079 ASSERT_EQ(loop_node_, NULL); | |
| 2080 AddAlternative(alt); | |
| 2081 loop_node_ = alt.node(); | |
| 2082 } | |
| 2083 | |
| 2084 | |
| 2085 void LoopChoiceNode::AddContinueAlternative(GuardedAlternative alt) { | |
| 2086 ASSERT_EQ(continue_node_, NULL); | |
| 2087 AddAlternative(alt); | |
| 2088 continue_node_ = alt.node(); | |
| 2089 } | |
| 2090 | |
| 2091 | |
| 2073 bool LoopChoiceNode::Emit(RegExpCompiler* compiler, | 2092 bool LoopChoiceNode::Emit(RegExpCompiler* compiler, |
| 2074 GenerationVariant* variant) { | 2093 GenerationVariant* variant) { |
| 2075 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler(); | 2094 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler(); |
| 2076 if (variant->stop_node() == this) { | 2095 if (variant->stop_node() == this) { |
| 2077 int text_length = GreedyLoopTextLength(&(alternatives_->at(0))); | 2096 int text_length = GreedyLoopTextLength(&(alternatives_->at(0))); |
| 2078 ASSERT(text_length != kNodeIsTooComplexForGreedyLoops); | 2097 ASSERT(text_length != kNodeIsTooComplexForGreedyLoops); |
| 2079 // Update the counter-based backtracking info on the stack. This is an | 2098 // Update the counter-based backtracking info on the stack. This is an |
| 2080 // optimization for greedy loops (see below). | 2099 // optimization for greedy loops (see below). |
| 2081 ASSERT(variant->cp_offset() == text_length); | 2100 ASSERT(variant->cp_offset() == text_length); |
| 2082 macro_assembler->AdvanceCurrentPosition(text_length); | 2101 macro_assembler->AdvanceCurrentPosition(text_length); |
| (...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2664 RegExpCompiler* compiler, | 2683 RegExpCompiler* compiler, |
| 2665 RegExpNode* on_success) { | 2684 RegExpNode* on_success) { |
| 2666 // x{f, t} becomes this: | 2685 // x{f, t} becomes this: |
| 2667 // | 2686 // |
| 2668 // (r++)<-. | 2687 // (r++)<-. |
| 2669 // | ` | 2688 // | ` |
| 2670 // | (x) | 2689 // | (x) |
| 2671 // v ^ | 2690 // v ^ |
| 2672 // (r=0)-->(?)---/ [if r < t] | 2691 // (r=0)-->(?)---/ [if r < t] |
| 2673 // | | 2692 // | |
| 2674 // [if r >= f] \----> ... | 2693 // [if r >= f] \----> ... |
|
Erik Corry
2008/12/17 13:14:41
Someone should build this in wrought iron and you
| |
| 2675 // | 2694 // |
| 2676 // | 2695 // |
| 2677 // TODO(someone): clear captures on repetition and handle empty | 2696 // TODO(someone): clear captures on repetition and handle empty |
| 2678 // matches. | 2697 // matches. |
| 2679 bool has_min = min > 0; | 2698 bool has_min = min > 0; |
| 2680 bool has_max = max < RegExpTree::kInfinity; | 2699 bool has_max = max < RegExpTree::kInfinity; |
| 2681 bool needs_counter = has_min || has_max; | 2700 bool needs_counter = has_min || has_max; |
| 2682 int reg_ctr = needs_counter ? compiler->AllocateRegister() : -1; | 2701 int reg_ctr = needs_counter ? compiler->AllocateRegister() : -1; |
| 2683 ChoiceNode* center = new LoopChoiceNode(2); | 2702 LoopChoiceNode* center = new LoopChoiceNode(); |
| 2684 RegExpNode* loop_return = needs_counter | 2703 RegExpNode* loop_return = needs_counter |
| 2685 ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center)) | 2704 ? static_cast<RegExpNode*>(ActionNode::IncrementRegister(reg_ctr, center)) |
| 2686 : static_cast<RegExpNode*>(center); | 2705 : static_cast<RegExpNode*>(center); |
| 2687 RegExpNode* body_node = body->ToNode(compiler, loop_return); | 2706 RegExpNode* body_node = body->ToNode(compiler, loop_return); |
| 2688 GuardedAlternative body_alt(body_node); | 2707 GuardedAlternative body_alt(body_node); |
| 2689 if (has_max) { | 2708 if (has_max) { |
| 2690 Guard* body_guard = new Guard(reg_ctr, Guard::LT, max); | 2709 Guard* body_guard = new Guard(reg_ctr, Guard::LT, max); |
| 2691 body_alt.AddGuard(body_guard); | 2710 body_alt.AddGuard(body_guard); |
| 2692 } | 2711 } |
| 2693 GuardedAlternative rest_alt(on_success); | 2712 GuardedAlternative rest_alt(on_success); |
| 2694 if (has_min) { | 2713 if (has_min) { |
| 2695 Guard* rest_guard = new Guard(reg_ctr, Guard::GEQ, min); | 2714 Guard* rest_guard = new Guard(reg_ctr, Guard::GEQ, min); |
| 2696 rest_alt.AddGuard(rest_guard); | 2715 rest_alt.AddGuard(rest_guard); |
| 2697 } | 2716 } |
| 2698 if (is_greedy) { | 2717 if (is_greedy) { |
| 2699 center->AddAlternative(body_alt); | 2718 center->AddLoopAlternative(body_alt); |
| 2700 center->AddAlternative(rest_alt); | 2719 center->AddContinueAlternative(rest_alt); |
| 2701 } else { | 2720 } else { |
| 2702 center->AddAlternative(rest_alt); | 2721 center->AddContinueAlternative(rest_alt); |
| 2703 center->AddAlternative(body_alt); | 2722 center->AddLoopAlternative(body_alt); |
| 2704 } | 2723 } |
| 2705 if (needs_counter) { | 2724 if (needs_counter) { |
| 2706 return ActionNode::SetRegister(reg_ctr, 0, center); | 2725 return ActionNode::SetRegister(reg_ctr, 0, center); |
| 2707 } else { | 2726 } else { |
| 2708 return center; | 2727 return center; |
| 2709 } | 2728 } |
| 2710 } | 2729 } |
| 2711 | 2730 |
| 2712 | 2731 |
| 2713 RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler, | 2732 RegExpNode* RegExpAssertion::ToNode(RegExpCompiler* compiler, |
| (...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3351 for (int i = 0; i < that->alternatives()->length(); i++) { | 3370 for (int i = 0; i < that->alternatives()->length(); i++) { |
| 3352 RegExpNode* node = that->alternatives()->at(i).node(); | 3371 RegExpNode* node = that->alternatives()->at(i).node(); |
| 3353 EnsureAnalyzed(node); | 3372 EnsureAnalyzed(node); |
| 3354 // Anything the following nodes need to know has to be known by | 3373 // Anything the following nodes need to know has to be known by |
| 3355 // this node also, so it can pass it on. | 3374 // this node also, so it can pass it on. |
| 3356 info->AddFromFollowing(node->info()); | 3375 info->AddFromFollowing(node->info()); |
| 3357 } | 3376 } |
| 3358 } | 3377 } |
| 3359 | 3378 |
| 3360 | 3379 |
| 3380 void AssertionPropagation::VisitLoopChoice(LoopChoiceNode* that) { | |
| 3381 NodeInfo* info = that->info(); | |
| 3382 for (int i = 0; i < that->alternatives()->length(); i++) { | |
| 3383 RegExpNode* node = that->alternatives()->at(i).node(); | |
| 3384 if (node != that->loop_node()) { | |
| 3385 EnsureAnalyzed(node); | |
| 3386 info->AddFromFollowing(node->info()); | |
| 3387 } | |
| 3388 } | |
| 3389 // Check the loop last since it may need the value of this node | |
| 3390 // to get a correct result. | |
| 3391 EnsureAnalyzed(that->loop_node()); | |
| 3392 info->AddFromFollowing(that->loop_node()->info()); | |
| 3393 } | |
| 3394 | |
| 3395 | |
| 3361 void AssertionPropagation::VisitBackReference(BackReferenceNode* that) { | 3396 void AssertionPropagation::VisitBackReference(BackReferenceNode* that) { |
| 3362 EnsureAnalyzed(that->on_success()); | 3397 EnsureAnalyzed(that->on_success()); |
| 3363 } | 3398 } |
| 3364 | 3399 |
| 3365 | 3400 |
| 3366 // ------------------------------------------------------------------- | 3401 // ------------------------------------------------------------------- |
| 3367 // Assumption expansion | 3402 // Assumption expansion |
| 3368 | 3403 |
| 3369 | 3404 |
| 3370 RegExpNode* RegExpNode::EnsureExpanded(NodeInfo* info) { | 3405 RegExpNode* RegExpNode::EnsureExpanded(NodeInfo* info) { |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3857 EmbeddedVector<byte, 1024> codes; | 3892 EmbeddedVector<byte, 1024> codes; |
| 3858 RegExpMacroAssemblerIrregexp macro_assembler(codes); | 3893 RegExpMacroAssemblerIrregexp macro_assembler(codes); |
| 3859 return compiler.Assemble(¯o_assembler, | 3894 return compiler.Assemble(¯o_assembler, |
| 3860 node, | 3895 node, |
| 3861 data->capture_count, | 3896 data->capture_count, |
| 3862 pattern); | 3897 pattern); |
| 3863 } | 3898 } |
| 3864 | 3899 |
| 3865 | 3900 |
| 3866 }} // namespace v8::internal | 3901 }} // namespace v8::internal |
| OLD | NEW |