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

Side by Side Diff: src/jsregexp.cc

Issue 14837: Remove assertion expansion. (Closed)
Patch Set: Added a bugfix Created 12 years 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
« no previous file with comments | « src/jsregexp.h ('k') | src/parser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2435 matching lines...) Expand 10 before | Expand all | Expand 10 after
2446 2446
2447 void DotPrinter::PrintAttributes(RegExpNode* that) { 2447 void DotPrinter::PrintAttributes(RegExpNode* that) {
2448 stream()->Add(" a%p [shape=Mrecord, color=grey, fontcolor=grey, " 2448 stream()->Add(" a%p [shape=Mrecord, color=grey, fontcolor=grey, "
2449 "margin=0.1, fontsize=10, label=\"{", 2449 "margin=0.1, fontsize=10, label=\"{",
2450 that); 2450 that);
2451 AttributePrinter printer(this); 2451 AttributePrinter printer(this);
2452 NodeInfo* info = that->info(); 2452 NodeInfo* info = that->info();
2453 printer.PrintBit("NI", info->follows_newline_interest); 2453 printer.PrintBit("NI", info->follows_newline_interest);
2454 printer.PrintBit("WI", info->follows_word_interest); 2454 printer.PrintBit("WI", info->follows_word_interest);
2455 printer.PrintBit("SI", info->follows_start_interest); 2455 printer.PrintBit("SI", info->follows_start_interest);
2456 printer.PrintBit("DN", info->determine_newline);
2457 printer.PrintBit("DW", info->determine_word);
2458 printer.PrintBit("DS", info->determine_start);
2459 printer.PrintBit("DDN", info->does_determine_newline);
2460 printer.PrintBit("DDW", info->does_determine_word);
2461 printer.PrintBit("DDS", info->does_determine_start);
2462 printer.PrintPositive("IW", info->is_word);
2463 printer.PrintPositive("IN", info->is_newline);
2464 printer.PrintPositive("FN", info->follows_newline);
2465 printer.PrintPositive("FW", info->follows_word);
2466 printer.PrintPositive("FS", info->follows_start);
2467 Label* label = that->label(); 2456 Label* label = that->label();
2468 if (label->is_bound()) 2457 if (label->is_bound())
2469 printer.PrintPositive("@", label->pos()); 2458 printer.PrintPositive("@", label->pos());
2470 stream()->Add("}\"];\n"); 2459 stream()->Add("}\"];\n");
2471 stream()->Add(" a%p -> n%p [style=dashed, color=grey, " 2460 stream()->Add(" a%p -> n%p [style=dashed, color=grey, "
2472 "arrowhead=none];\n", that, that); 2461 "arrowhead=none];\n", that, that);
2473 } 2462 }
2474 2463
2475 2464
2476 static const bool kPrintDispatchTable = false; 2465 static const bool kPrintDispatchTable = false;
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
3068 RegExpNode* sibling = siblings_.Get(i); 3057 RegExpNode* sibling = siblings_.Get(i);
3069 if (sibling->info()->Matches(info)) 3058 if (sibling->info()->Matches(info))
3070 return sibling; 3059 return sibling;
3071 } 3060 }
3072 return NULL; 3061 return NULL;
3073 } 3062 }
3074 3063
3075 3064
3076 RegExpNode* RegExpNode::EnsureSibling(NodeInfo* info, bool* cloned) { 3065 RegExpNode* RegExpNode::EnsureSibling(NodeInfo* info, bool* cloned) {
3077 ASSERT_EQ(false, *cloned); 3066 ASSERT_EQ(false, *cloned);
3078 ASSERT(!info->HasAssertions());
3079 siblings_.Ensure(this); 3067 siblings_.Ensure(this);
3080 RegExpNode* result = TryGetSibling(info); 3068 RegExpNode* result = TryGetSibling(info);
3081 if (result != NULL) return result; 3069 if (result != NULL) return result;
3082 result = this->Clone(); 3070 result = this->Clone();
3083 NodeInfo* new_info = result->info(); 3071 NodeInfo* new_info = result->info();
3084 new_info->ResetCompilationState(); 3072 new_info->ResetCompilationState();
3085 new_info->AddFromPreceding(info); 3073 new_info->AddFromPreceding(info);
3086 AddSibling(result); 3074 AddSibling(result);
3087 *cloned = true; 3075 *cloned = true;
3088 return result; 3076 return result;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
3300 return entry->out_set(); 3288 return entry->out_set();
3301 else 3289 else
3302 return empty(); 3290 return empty();
3303 } 3291 }
3304 3292
3305 3293
3306 // ------------------------------------------------------------------- 3294 // -------------------------------------------------------------------
3307 // Analysis 3295 // Analysis
3308 3296
3309 3297
3310 void AssertionPropagation::EnsureAnalyzed(RegExpNode* that) { 3298 void Analysis::EnsureAnalyzed(RegExpNode* that) {
3311 if (that->info()->been_analyzed || that->info()->being_analyzed) 3299 if (that->info()->been_analyzed || that->info()->being_analyzed)
3312 return; 3300 return;
3313 that->info()->being_analyzed = true; 3301 that->info()->being_analyzed = true;
3314 that->Accept(this); 3302 that->Accept(this);
3315 that->info()->being_analyzed = false; 3303 that->info()->being_analyzed = false;
3316 that->info()->been_analyzed = true; 3304 that->info()->been_analyzed = true;
3317 } 3305 }
3318 3306
3319 3307
3320 void AssertionPropagation::VisitEnd(EndNode* that) { 3308 void Analysis::VisitEnd(EndNode* that) {
3321 // nothing to do 3309 // nothing to do
3322 } 3310 }
3323 3311
3324 3312
3325 void TextNode::CalculateOffsets() { 3313 void TextNode::CalculateOffsets() {
3326 int element_count = elements()->length(); 3314 int element_count = elements()->length();
3327 // Set up the offsets of the elements relative to the start. This is a fixed 3315 // Set up the offsets of the elements relative to the start. This is a fixed
3328 // quantity since a TextNode can only contain fixed-width things. 3316 // quantity since a TextNode can only contain fixed-width things.
3329 int cp_offset = 0; 3317 int cp_offset = 0;
3330 for (int i = 0; i < element_count; i++) { 3318 for (int i = 0; i < element_count; i++) {
3331 TextElement& elm = elements()->at(i); 3319 TextElement& elm = elements()->at(i);
3332 elm.cp_offset = cp_offset; 3320 elm.cp_offset = cp_offset;
3333 if (elm.type == TextElement::ATOM) { 3321 if (elm.type == TextElement::ATOM) {
3334 cp_offset += elm.data.u_atom->data().length(); 3322 cp_offset += elm.data.u_atom->data().length();
3335 } else { 3323 } else {
3336 cp_offset++; 3324 cp_offset++;
3337 Vector<const uc16> quarks = elm.data.u_atom->data(); 3325 Vector<const uc16> quarks = elm.data.u_atom->data();
3338 } 3326 }
3339 } 3327 }
3340 } 3328 }
3341 3329
3342 3330
3343 void AssertionPropagation::VisitText(TextNode* that) { 3331 void Analysis::VisitText(TextNode* that) {
3344 if (ignore_case_) { 3332 if (ignore_case_) {
3345 that->MakeCaseIndependent(); 3333 that->MakeCaseIndependent();
3346 } 3334 }
3347 EnsureAnalyzed(that->on_success()); 3335 EnsureAnalyzed(that->on_success());
3348 NodeInfo* info = that->info();
3349 NodeInfo* next_info = that->on_success()->info();
3350 // If the following node is interested in what it follows then this
3351 // node must determine it.
3352 info->determine_newline = next_info->follows_newline_interest;
3353 info->determine_word = next_info->follows_word_interest;
3354 info->determine_start = next_info->follows_start_interest;
3355 that->CalculateOffsets(); 3336 that->CalculateOffsets();
3356 } 3337 }
3357 3338
3358 3339
3359 void AssertionPropagation::VisitAction(ActionNode* that) { 3340 void Analysis::VisitAction(ActionNode* that) {
3360 RegExpNode* target = that->on_success(); 3341 RegExpNode* target = that->on_success();
3361 EnsureAnalyzed(target); 3342 EnsureAnalyzed(target);
3362 // If the next node is interested in what it follows then this node 3343 // If the next node is interested in what it follows then this node
3363 // has to be interested too so it can pass the information on. 3344 // has to be interested too so it can pass the information on.
3364 that->info()->AddFromFollowing(target->info()); 3345 that->info()->AddFromFollowing(target->info());
3365 } 3346 }
3366 3347
3367 3348
3368 void AssertionPropagation::VisitChoice(ChoiceNode* that) { 3349 void Analysis::VisitChoice(ChoiceNode* that) {
3369 NodeInfo* info = that->info(); 3350 NodeInfo* info = that->info();
3370 for (int i = 0; i < that->alternatives()->length(); i++) { 3351 for (int i = 0; i < that->alternatives()->length(); i++) {
3371 RegExpNode* node = that->alternatives()->at(i).node(); 3352 RegExpNode* node = that->alternatives()->at(i).node();
3372 EnsureAnalyzed(node); 3353 EnsureAnalyzed(node);
3373 // Anything the following nodes need to know has to be known by 3354 // Anything the following nodes need to know has to be known by
3374 // this node also, so it can pass it on. 3355 // this node also, so it can pass it on.
3375 info->AddFromFollowing(node->info()); 3356 info->AddFromFollowing(node->info());
3376 } 3357 }
3377 } 3358 }
3378 3359
3379 3360
3380 void AssertionPropagation::VisitLoopChoice(LoopChoiceNode* that) { 3361 void Analysis::VisitLoopChoice(LoopChoiceNode* that) {
3381 NodeInfo* info = that->info(); 3362 NodeInfo* info = that->info();
3382 for (int i = 0; i < that->alternatives()->length(); i++) { 3363 for (int i = 0; i < that->alternatives()->length(); i++) {
3383 RegExpNode* node = that->alternatives()->at(i).node(); 3364 RegExpNode* node = that->alternatives()->at(i).node();
3384 if (node != that->loop_node()) { 3365 if (node != that->loop_node()) {
3385 EnsureAnalyzed(node); 3366 EnsureAnalyzed(node);
3386 info->AddFromFollowing(node->info()); 3367 info->AddFromFollowing(node->info());
3387 } 3368 }
3388 } 3369 }
3389 // Check the loop last since it may need the value of this node 3370 // Check the loop last since it may need the value of this node
3390 // to get a correct result. 3371 // to get a correct result.
3391 EnsureAnalyzed(that->loop_node()); 3372 EnsureAnalyzed(that->loop_node());
3392 info->AddFromFollowing(that->loop_node()->info()); 3373 info->AddFromFollowing(that->loop_node()->info());
3393 } 3374 }
3394 3375
3395 3376
3396 void AssertionPropagation::VisitBackReference(BackReferenceNode* that) { 3377 void Analysis::VisitBackReference(BackReferenceNode* that) {
3397 EnsureAnalyzed(that->on_success()); 3378 EnsureAnalyzed(that->on_success());
3398 } 3379 }
3399 3380
3400 3381
3401 // ------------------------------------------------------------------- 3382 // -------------------------------------------------------------------
3402 // Assumption expansion
3403
3404
3405 RegExpNode* RegExpNode::EnsureExpanded(NodeInfo* info) {
3406 siblings_.Ensure(this);
3407 NodeInfo new_info = *this->info();
3408 if (new_info.follows_word_interest)
3409 new_info.follows_word = info->follows_word;
3410 if (new_info.follows_newline_interest)
3411 new_info.follows_newline = info->follows_newline;
3412 // If the following node should determine something we need to get
3413 // a sibling that determines it.
3414 new_info.does_determine_newline = new_info.determine_newline;
3415 new_info.does_determine_word = new_info.determine_word;
3416 new_info.does_determine_start = new_info.determine_start;
3417 RegExpNode* sibling = TryGetSibling(&new_info);
3418 if (sibling == NULL) {
3419 sibling = ExpandLocal(&new_info);
3420 siblings_.Add(sibling);
3421 sibling->info()->being_expanded = true;
3422 sibling->ExpandChildren();
3423 sibling->info()->being_expanded = false;
3424 sibling->info()->been_expanded = true;
3425 } else {
3426 NodeInfo* sib_info = sibling->info();
3427 if (!sib_info->been_expanded && !sib_info->being_expanded) {
3428 sibling->info()->being_expanded = true;
3429 sibling->ExpandChildren();
3430 sibling->info()->being_expanded = false;
3431 sibling->info()->been_expanded = true;
3432 }
3433 }
3434 return sibling;
3435 }
3436
3437
3438 RegExpNode* ChoiceNode::ExpandLocal(NodeInfo* info) {
3439 ChoiceNode* clone = this->Clone();
3440 clone->info()->ResetCompilationState();
3441 clone->info()->AddAssumptions(info);
3442 return clone;
3443 }
3444
3445
3446 void ChoiceNode::ExpandChildren() {
3447 ZoneList<GuardedAlternative>* alts = alternatives();
3448 ZoneList<GuardedAlternative>* new_alts
3449 = new ZoneList<GuardedAlternative>(alts->length());
3450 for (int i = 0; i < alts->length(); i++) {
3451 GuardedAlternative next = alts->at(i);
3452 next.set_node(next.node()->EnsureExpanded(info()));
3453 new_alts->Add(next);
3454 }
3455 alternatives_ = new_alts;
3456 }
3457
3458
3459 RegExpNode* TextNode::ExpandLocal(NodeInfo* info) {
3460 TextElement last = elements()->last();
3461 if (last.type == TextElement::CHAR_CLASS) {
3462 RegExpCharacterClass* char_class = last.data.u_char_class;
3463 if (info->does_determine_word) {
3464 ZoneList<CharacterRange>* word = NULL;
3465 ZoneList<CharacterRange>* non_word = NULL;
3466 CharacterRange::Split(char_class->ranges(),
3467 CharacterRange::GetWordBounds(),
3468 &word,
3469 &non_word);
3470 if (non_word == NULL) {
3471 // This node contains no non-word characters so it must be
3472 // all word.
3473 this->info()->is_word = NodeInfo::TRUE;
3474 } else if (word == NULL) {
3475 // Vice versa.
3476 this->info()->is_word = NodeInfo::FALSE;
3477 } else {
3478 // If this character class contains both word and non-word
3479 // characters we need to split it into two.
3480 ChoiceNode* result = new ChoiceNode(2);
3481 // Welcome to the family, son!
3482 result->set_siblings(this->siblings());
3483 *result->info() = *this->info();
3484 result->info()->ResetCompilationState();
3485 result->info()->AddAssumptions(info);
3486 RegExpNode* word_node
3487 = new TextNode(new RegExpCharacterClass(word, false),
3488 on_success());
3489 word_node->info()->determine_word = true;
3490 word_node->info()->does_determine_word = true;
3491 word_node->info()->is_word = NodeInfo::TRUE;
3492 result->alternatives()->Add(GuardedAlternative(word_node));
3493 RegExpNode* non_word_node
3494 = new TextNode(new RegExpCharacterClass(non_word, false),
3495 on_success());
3496 non_word_node->info()->determine_word = true;
3497 non_word_node->info()->does_determine_word = true;
3498 non_word_node->info()->is_word = NodeInfo::FALSE;
3499 result->alternatives()->Add(GuardedAlternative(non_word_node));
3500 return result;
3501 }
3502 }
3503 }
3504 TextNode* clone = this->Clone();
3505 clone->info()->ResetCompilationState();
3506 clone->info()->AddAssumptions(info);
3507 return clone;
3508 }
3509
3510
3511 void TextNode::ExpandAtomChildren(RegExpAtom* that) {
3512 NodeInfo new_info = *info();
3513 uc16 last = that->data()[that->data().length() - 1];
3514 if (info()->determine_word) {
3515 new_info.follows_word = IsRegExpWord(last)
3516 ? NodeInfo::TRUE : NodeInfo::FALSE;
3517 } else {
3518 new_info.follows_word = NodeInfo::UNKNOWN;
3519 }
3520 if (info()->determine_newline) {
3521 new_info.follows_newline = IsRegExpNewline(last)
3522 ? NodeInfo::TRUE : NodeInfo::FALSE;
3523 } else {
3524 new_info.follows_newline = NodeInfo::UNKNOWN;
3525 }
3526 if (info()->determine_start) {
3527 new_info.follows_start = NodeInfo::FALSE;
3528 } else {
3529 new_info.follows_start = NodeInfo::UNKNOWN;
3530 }
3531 set_on_success(on_success()->EnsureExpanded(&new_info));
3532 }
3533
3534
3535 void TextNode::ExpandCharClassChildren(RegExpCharacterClass* that) {
3536 if (info()->does_determine_word) {
3537 // ASSERT(info()->is_word != NodeInfo::UNKNOWN);
3538 NodeInfo next_info = *on_success()->info();
3539 next_info.follows_word = info()->is_word;
3540 set_on_success(on_success()->EnsureExpanded(&next_info));
3541 } else {
3542 set_on_success(on_success()->EnsureExpanded(info()));
3543 }
3544 }
3545
3546
3547 void TextNode::ExpandChildren() {
3548 TextElement last = elements()->last();
3549 switch (last.type) {
3550 case TextElement::ATOM:
3551 ExpandAtomChildren(last.data.u_atom);
3552 break;
3553 case TextElement::CHAR_CLASS:
3554 ExpandCharClassChildren(last.data.u_char_class);
3555 break;
3556 default:
3557 UNREACHABLE();
3558 }
3559 }
3560
3561
3562 RegExpNode* ActionNode::ExpandLocal(NodeInfo* info) {
3563 ActionNode* clone = this->Clone();
3564 clone->info()->ResetCompilationState();
3565 clone->info()->AddAssumptions(info);
3566 return clone;
3567 }
3568
3569
3570 void ActionNode::ExpandChildren() {
3571 set_on_success(on_success()->EnsureExpanded(info()));
3572 }
3573
3574
3575 RegExpNode* BackReferenceNode::ExpandLocal(NodeInfo* info) {
3576 BackReferenceNode* clone = this->Clone();
3577 clone->info()->ResetCompilationState();
3578 clone->info()->AddAssumptions(info);
3579 return clone;
3580 }
3581
3582
3583 void BackReferenceNode::ExpandChildren() {
3584 set_on_success(on_success()->EnsureExpanded(info()));
3585 }
3586
3587
3588 RegExpNode* EndNode::ExpandLocal(NodeInfo* info) {
3589 EndNode* clone = this->Clone();
3590 clone->info()->ResetCompilationState();
3591 clone->info()->AddAssumptions(info);
3592 return clone;
3593 }
3594
3595
3596 void EndNode::ExpandChildren() {
3597 // nothing to do
3598 }
3599
3600
3601 // -------------------------------------------------------------------
3602 // Dispatch table construction 3383 // Dispatch table construction
3603 3384
3604 3385
3605 void DispatchTableConstructor::VisitEnd(EndNode* that) { 3386 void DispatchTableConstructor::VisitEnd(EndNode* that) {
3606 AddRange(CharacterRange::Everything()); 3387 AddRange(CharacterRange::Everything());
3607 } 3388 }
3608 3389
3609 3390
3610 void DispatchTableConstructor::BuildTable(ChoiceNode* node) { 3391 void DispatchTableConstructor::BuildTable(ChoiceNode* node) {
3611 node->set_being_calculated(true); 3392 node->set_being_calculated(true);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
3701 } 3482 }
3702 } 3483 }
3703 3484
3704 3485
3705 void DispatchTableConstructor::VisitAction(ActionNode* that) { 3486 void DispatchTableConstructor::VisitAction(ActionNode* that) {
3706 RegExpNode* target = that->on_success(); 3487 RegExpNode* target = that->on_success();
3707 target->Accept(this); 3488 target->Accept(this);
3708 } 3489 }
3709 3490
3710 3491
3711 #ifdef DEBUG
3712
3713
3714 class VisitNodeScope {
3715 public:
3716 explicit VisitNodeScope(RegExpNode* node) : node_(node) {
3717 ASSERT(!node->info()->visited);
3718 node->info()->visited = true;
3719 }
3720 ~VisitNodeScope() {
3721 node_->info()->visited = false;
3722 }
3723 private:
3724 RegExpNode* node_;
3725 };
3726
3727
3728 class NodeValidator : public NodeVisitor {
3729 public:
3730 virtual void ValidateInfo(NodeInfo* info) = 0;
3731 #define DECLARE_VISIT(Type) \
3732 virtual void Visit##Type(Type##Node* that);
3733 FOR_EACH_NODE_TYPE(DECLARE_VISIT)
3734 #undef DECLARE_VISIT
3735 };
3736
3737
3738 class PostAnalysisNodeValidator : public NodeValidator {
3739 public:
3740 virtual void ValidateInfo(NodeInfo* info);
3741 };
3742
3743
3744 class PostExpansionNodeValidator : public NodeValidator {
3745 public:
3746 virtual void ValidateInfo(NodeInfo* info);
3747 };
3748
3749
3750 void PostAnalysisNodeValidator::ValidateInfo(NodeInfo* info) {
3751 ASSERT(info->been_analyzed);
3752 }
3753
3754
3755 void PostExpansionNodeValidator::ValidateInfo(NodeInfo* info) {
3756 ASSERT_EQ(info->determine_newline, info->does_determine_newline);
3757 ASSERT_EQ(info->determine_start, info->does_determine_start);
3758 ASSERT_EQ(info->determine_word, info->does_determine_word);
3759 ASSERT_EQ(info->follows_word_interest,
3760 (info->follows_word != NodeInfo::UNKNOWN));
3761 if (false) {
3762 // These are still unimplemented.
3763 ASSERT_EQ(info->follows_start_interest,
3764 (info->follows_start != NodeInfo::UNKNOWN));
3765 ASSERT_EQ(info->follows_newline_interest,
3766 (info->follows_newline != NodeInfo::UNKNOWN));
3767 }
3768 }
3769
3770
3771 void NodeValidator::VisitAction(ActionNode* that) {
3772 if (that->info()->visited) return;
3773 VisitNodeScope scope(that);
3774 ValidateInfo(that->info());
3775 that->on_success()->Accept(this);
3776 }
3777
3778
3779 void NodeValidator::VisitBackReference(BackReferenceNode* that) {
3780 if (that->info()->visited) return;
3781 VisitNodeScope scope(that);
3782 ValidateInfo(that->info());
3783 that->on_success()->Accept(this);
3784 }
3785
3786
3787 void NodeValidator::VisitChoice(ChoiceNode* that) {
3788 if (that->info()->visited) return;
3789 VisitNodeScope scope(that);
3790 ValidateInfo(that->info());
3791 ZoneList<GuardedAlternative>* alts = that->alternatives();
3792 for (int i = 0; i < alts->length(); i++)
3793 alts->at(i).node()->Accept(this);
3794 }
3795
3796
3797 void NodeValidator::VisitEnd(EndNode* that) {
3798 if (that->info()->visited) return;
3799 VisitNodeScope scope(that);
3800 ValidateInfo(that->info());
3801 }
3802
3803
3804 void NodeValidator::VisitText(TextNode* that) {
3805 if (that->info()->visited) return;
3806 VisitNodeScope scope(that);
3807 ValidateInfo(that->info());
3808 that->on_success()->Accept(this);
3809 }
3810
3811
3812 #endif
3813
3814
3815 Handle<FixedArray> RegExpEngine::Compile(RegExpCompileData* data, 3492 Handle<FixedArray> RegExpEngine::Compile(RegExpCompileData* data,
3816 bool ignore_case, 3493 bool ignore_case,
3817 bool is_multiline, 3494 bool is_multiline,
3818 Handle<String> pattern, 3495 Handle<String> pattern,
3819 bool is_ascii) { 3496 bool is_ascii) {
3820 RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii); 3497 RegExpCompiler compiler(data->capture_count, ignore_case, is_ascii);
3821 // Wrap the body of the regexp in capture #0. 3498 // Wrap the body of the regexp in capture #0.
3822 RegExpNode* captured_body = RegExpCapture::ToNode(data->tree, 3499 RegExpNode* captured_body = RegExpCapture::ToNode(data->tree,
3823 0, 3500 0,
3824 &compiler, 3501 &compiler,
3825 compiler.accept()); 3502 compiler.accept());
3826 // Add a .*? at the beginning, outside the body capture. 3503 // Add a .*? at the beginning, outside the body capture.
3827 // Note: We could choose to not add this if the regexp is anchored at 3504 // Note: We could choose to not add this if the regexp is anchored at
3828 // the start of the input but I'm not sure how best to do that and 3505 // the start of the input but I'm not sure how best to do that and
3829 // since we don't even handle ^ yet I'm saving that optimization for 3506 // since we don't even handle ^ yet I'm saving that optimization for
3830 // later. 3507 // later.
3831 RegExpNode* node = RegExpQuantifier::ToNode(0, 3508 RegExpNode* node = RegExpQuantifier::ToNode(0,
3832 RegExpTree::kInfinity, 3509 RegExpTree::kInfinity,
3833 false, 3510 false,
3834 new RegExpCharacterClass('*'), 3511 new RegExpCharacterClass('*'),
3835 &compiler, 3512 &compiler,
3836 captured_body); 3513 captured_body);
3837 AssertionPropagation analysis(ignore_case); 3514 data->node = node;
3515 Analysis analysis(ignore_case);
3838 analysis.EnsureAnalyzed(node); 3516 analysis.EnsureAnalyzed(node);
3839 3517
3840 NodeInfo info = *node->info(); 3518 NodeInfo info = *node->info();
3841 data->has_lookbehind = info.HasLookbehind();
3842 if (data->has_lookbehind) {
3843 // If this node needs information about the preceding text we let
3844 // it start with a character class that consumes a single character
3845 // and proceeds to wherever is appropriate. This means that if
3846 // has_lookbehind is set the code generator must start one character
3847 // before the start position.
3848 node = new TextNode(new RegExpCharacterClass('*'), node);
3849 analysis.EnsureAnalyzed(node);
3850 }
3851
3852 #ifdef DEBUG
3853 PostAnalysisNodeValidator post_analysis_validator;
3854 node->Accept(&post_analysis_validator);
3855 #endif
3856
3857 node = node->EnsureExpanded(&info);
3858
3859 #ifdef DEBUG
3860 PostExpansionNodeValidator post_expansion_validator;
3861 node->Accept(&post_expansion_validator);
3862 #endif
3863
3864 data->node = node;
3865 3519
3866 if (is_multiline && !FLAG_attempt_multiline_irregexp) { 3520 if (is_multiline && !FLAG_attempt_multiline_irregexp) {
3867 return Handle<FixedArray>::null(); 3521 return Handle<FixedArray>::null();
3868 } 3522 }
3869 3523
3870 if (data->has_lookbehind) {
3871 return Handle<FixedArray>::null();
3872 }
3873
3874 if (FLAG_irregexp_native) { 3524 if (FLAG_irregexp_native) {
3875 #ifdef ARM 3525 #ifdef ARM
3876 // Unimplemented, fall-through to bytecode implementation. 3526 // Unimplemented, fall-through to bytecode implementation.
3877 #else // IA32 3527 #else // IA32
3878 RegExpMacroAssemblerIA32::Mode mode; 3528 RegExpMacroAssemblerIA32::Mode mode;
3879 if (is_ascii) { 3529 if (is_ascii) {
3880 mode = RegExpMacroAssemblerIA32::ASCII; 3530 mode = RegExpMacroAssemblerIA32::ASCII;
3881 } else { 3531 } else {
3882 mode = RegExpMacroAssemblerIA32::UC16; 3532 mode = RegExpMacroAssemblerIA32::UC16;
3883 } 3533 }
3884 RegExpMacroAssemblerIA32 macro_assembler(mode, 3534 RegExpMacroAssemblerIA32 macro_assembler(mode,
3885 (data->capture_count + 1) * 2); 3535 (data->capture_count + 1) * 2);
3886 return compiler.Assemble(&macro_assembler, 3536 return compiler.Assemble(&macro_assembler,
3887 node, 3537 node,
3888 data->capture_count, 3538 data->capture_count,
3889 pattern); 3539 pattern);
3890 #endif 3540 #endif
3891 } 3541 }
3892 EmbeddedVector<byte, 1024> codes; 3542 EmbeddedVector<byte, 1024> codes;
3893 RegExpMacroAssemblerIrregexp macro_assembler(codes); 3543 RegExpMacroAssemblerIrregexp macro_assembler(codes);
3894 return compiler.Assemble(&macro_assembler, 3544 return compiler.Assemble(&macro_assembler,
3895 node, 3545 node,
3896 data->capture_count, 3546 data->capture_count,
3897 pattern); 3547 pattern);
3898 } 3548 }
3899 3549
3900 3550
3901 }} // namespace v8::internal 3551 }} // namespace v8::internal
OLDNEW
« no previous file with comments | « src/jsregexp.h ('k') | src/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698