| 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 2281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2292 | 2292 |
| 2293 // If we get here code has been generated for this node too many times or | 2293 // If we get here code has been generated for this node too many times or |
| 2294 // recursion is too deep. Time to switch to a generic version. The code for | 2294 // recursion is too deep. Time to switch to a generic version. The code for |
| 2295 // generic versions above can handle deep recursion properly. | 2295 // generic versions above can handle deep recursion properly. |
| 2296 trace->Flush(compiler, this); | 2296 trace->Flush(compiler, this); |
| 2297 return DONE; | 2297 return DONE; |
| 2298 } | 2298 } |
| 2299 | 2299 |
| 2300 | 2300 |
| 2301 int ActionNode::EatsAtLeast(int still_to_find, | 2301 int ActionNode::EatsAtLeast(int still_to_find, |
| 2302 int recursion_depth, | 2302 int budget, |
| 2303 bool not_at_start) { | 2303 bool not_at_start) { |
| 2304 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; | 2304 if (budget <= 0) return 0; |
| 2305 if (type_ == POSITIVE_SUBMATCH_SUCCESS) return 0; // Rewinds input! | 2305 if (type_ == POSITIVE_SUBMATCH_SUCCESS) return 0; // Rewinds input! |
| 2306 return on_success()->EatsAtLeast(still_to_find, | 2306 return on_success()->EatsAtLeast(still_to_find, |
| 2307 recursion_depth + 1, | 2307 budget - 1, |
| 2308 not_at_start); | 2308 not_at_start); |
| 2309 } | 2309 } |
| 2310 | 2310 |
| 2311 | 2311 |
| 2312 void ActionNode::FillInBMInfo(int offset, | 2312 void ActionNode::FillInBMInfo(int offset, |
| 2313 int recursion_depth, | |
| 2314 int budget, | 2313 int budget, |
| 2315 BoyerMooreLookahead* bm, | 2314 BoyerMooreLookahead* bm, |
| 2316 bool not_at_start) { | 2315 bool not_at_start) { |
| 2317 if (type_ == BEGIN_SUBMATCH) { | 2316 if (type_ == BEGIN_SUBMATCH) { |
| 2318 bm->SetRest(offset); | 2317 bm->SetRest(offset); |
| 2319 } else if (type_ != POSITIVE_SUBMATCH_SUCCESS) { | 2318 } else if (type_ != POSITIVE_SUBMATCH_SUCCESS) { |
| 2320 on_success()->FillInBMInfo( | 2319 on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start); |
| 2321 offset, recursion_depth + 1, budget - 1, bm, not_at_start); | |
| 2322 } | 2320 } |
| 2323 SaveBMInfo(bm, not_at_start, offset); | 2321 SaveBMInfo(bm, not_at_start, offset); |
| 2324 } | 2322 } |
| 2325 | 2323 |
| 2326 | 2324 |
| 2327 int AssertionNode::EatsAtLeast(int still_to_find, | 2325 int AssertionNode::EatsAtLeast(int still_to_find, |
| 2328 int recursion_depth, | 2326 int budget, |
| 2329 bool not_at_start) { | 2327 bool not_at_start) { |
| 2330 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; | 2328 if (budget <= 0) return 0; |
| 2331 // If we know we are not at the start and we are asked "how many characters | 2329 // 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 | 2330 // 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 | 2331 // 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 | 2332 // that won't prevent us from preloading a lot of characters for the other |
| 2335 // branches in the node graph. | 2333 // branches in the node graph. |
| 2336 if (type() == AT_START && not_at_start) return still_to_find; | 2334 if (type() == AT_START && not_at_start) return still_to_find; |
| 2337 return on_success()->EatsAtLeast(still_to_find, | 2335 return on_success()->EatsAtLeast(still_to_find, |
| 2338 recursion_depth + 1, | 2336 budget - 1, |
| 2339 not_at_start); | 2337 not_at_start); |
| 2340 } | 2338 } |
| 2341 | 2339 |
| 2342 | 2340 |
| 2343 void AssertionNode::FillInBMInfo(int offset, | 2341 void AssertionNode::FillInBMInfo(int offset, |
| 2344 int recursion_depth, | |
| 2345 int budget, | 2342 int budget, |
| 2346 BoyerMooreLookahead* bm, | 2343 BoyerMooreLookahead* bm, |
| 2347 bool not_at_start) { | 2344 bool not_at_start) { |
| 2348 // Match the behaviour of EatsAtLeast on this node. | 2345 // Match the behaviour of EatsAtLeast on this node. |
| 2349 if (type() == AT_START && not_at_start) return; | 2346 if (type() == AT_START && not_at_start) return; |
| 2350 on_success()->FillInBMInfo( | 2347 on_success()->FillInBMInfo(offset, budget - 1, bm, not_at_start); |
| 2351 offset, recursion_depth + 1, budget - 1, bm, not_at_start); | |
| 2352 SaveBMInfo(bm, not_at_start, offset); | 2348 SaveBMInfo(bm, not_at_start, offset); |
| 2353 } | 2349 } |
| 2354 | 2350 |
| 2355 | 2351 |
| 2356 int BackReferenceNode::EatsAtLeast(int still_to_find, | 2352 int BackReferenceNode::EatsAtLeast(int still_to_find, |
| 2357 int recursion_depth, | 2353 int budget, |
| 2358 bool not_at_start) { | 2354 bool not_at_start) { |
| 2359 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; | 2355 if (budget <= 0) return 0; |
| 2360 return on_success()->EatsAtLeast(still_to_find, | 2356 return on_success()->EatsAtLeast(still_to_find, |
| 2361 recursion_depth + 1, | 2357 budget - 1, |
| 2362 not_at_start); | 2358 not_at_start); |
| 2363 } | 2359 } |
| 2364 | 2360 |
| 2365 | 2361 |
| 2366 int TextNode::EatsAtLeast(int still_to_find, | 2362 int TextNode::EatsAtLeast(int still_to_find, |
| 2367 int recursion_depth, | 2363 int budget, |
| 2368 bool not_at_start) { | 2364 bool not_at_start) { |
| 2369 int answer = Length(); | 2365 int answer = Length(); |
| 2370 if (answer >= still_to_find) return answer; | 2366 if (answer >= still_to_find) return answer; |
| 2371 if (recursion_depth > RegExpCompiler::kMaxRecursion) return answer; | 2367 if (budget <= 0) return answer; |
| 2372 // We are not at start after this node so we set the last argument to 'true'. | 2368 // We are not at start after this node so we set the last argument to 'true'. |
| 2373 return answer + on_success()->EatsAtLeast(still_to_find - answer, | 2369 return answer + on_success()->EatsAtLeast(still_to_find - answer, |
| 2374 recursion_depth + 1, | 2370 budget - 1, |
| 2375 true); | 2371 true); |
| 2376 } | 2372 } |
| 2377 | 2373 |
| 2378 | 2374 |
| 2379 int NegativeLookaheadChoiceNode::EatsAtLeast(int still_to_find, | 2375 int NegativeLookaheadChoiceNode::EatsAtLeast(int still_to_find, |
| 2380 int recursion_depth, | 2376 int budget, |
| 2381 bool not_at_start) { | 2377 bool not_at_start) { |
| 2382 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; | 2378 if (budget <= 0) return 0; |
| 2383 // Alternative 0 is the negative lookahead, alternative 1 is what comes | 2379 // Alternative 0 is the negative lookahead, alternative 1 is what comes |
| 2384 // afterwards. | 2380 // afterwards. |
| 2385 RegExpNode* node = alternatives_->at(1).node(); | 2381 RegExpNode* node = alternatives_->at(1).node(); |
| 2386 return node->EatsAtLeast(still_to_find, recursion_depth + 1, not_at_start); | 2382 return node->EatsAtLeast(still_to_find, budget - 1, not_at_start); |
| 2387 } | 2383 } |
| 2388 | 2384 |
| 2389 | 2385 |
| 2390 void NegativeLookaheadChoiceNode::GetQuickCheckDetails( | 2386 void NegativeLookaheadChoiceNode::GetQuickCheckDetails( |
| 2391 QuickCheckDetails* details, | 2387 QuickCheckDetails* details, |
| 2392 RegExpCompiler* compiler, | 2388 RegExpCompiler* compiler, |
| 2393 int filled_in, | 2389 int filled_in, |
| 2394 bool not_at_start) { | 2390 bool not_at_start) { |
| 2395 // Alternative 0 is the negative lookahead, alternative 1 is what comes | 2391 // Alternative 0 is the negative lookahead, alternative 1 is what comes |
| 2396 // afterwards. | 2392 // afterwards. |
| 2397 RegExpNode* node = alternatives_->at(1).node(); | 2393 RegExpNode* node = alternatives_->at(1).node(); |
| 2398 return node->GetQuickCheckDetails(details, compiler, filled_in, not_at_start); | 2394 return node->GetQuickCheckDetails(details, compiler, filled_in, not_at_start); |
| 2399 } | 2395 } |
| 2400 | 2396 |
| 2401 | 2397 |
| 2402 int ChoiceNode::EatsAtLeastHelper(int still_to_find, | 2398 int ChoiceNode::EatsAtLeastHelper(int still_to_find, |
| 2403 int recursion_depth, | 2399 int budget, |
| 2404 RegExpNode* ignore_this_node, | 2400 RegExpNode* ignore_this_node, |
| 2405 bool not_at_start) { | 2401 bool not_at_start) { |
| 2406 if (recursion_depth > RegExpCompiler::kMaxRecursion) return 0; | 2402 if (budget <= 0) return 0; |
| 2407 int min = 100; | 2403 int min = 100; |
| 2408 int choice_count = alternatives_->length(); | 2404 int choice_count = alternatives_->length(); |
| 2405 budget = (budget - 1) / choice_count; |
| 2409 for (int i = 0; i < choice_count; i++) { | 2406 for (int i = 0; i < choice_count; i++) { |
| 2410 RegExpNode* node = alternatives_->at(i).node(); | 2407 RegExpNode* node = alternatives_->at(i).node(); |
| 2411 if (node == ignore_this_node) continue; | 2408 if (node == ignore_this_node) continue; |
| 2412 int node_eats_at_least = node->EatsAtLeast(still_to_find, | 2409 int node_eats_at_least = |
| 2413 recursion_depth + 1, | 2410 node->EatsAtLeast(still_to_find, budget, not_at_start); |
| 2414 not_at_start); | |
| 2415 if (node_eats_at_least < min) min = node_eats_at_least; | 2411 if (node_eats_at_least < min) min = node_eats_at_least; |
| 2412 if (min == 0) return 0; |
| 2416 } | 2413 } |
| 2417 return min; | 2414 return min; |
| 2418 } | 2415 } |
| 2419 | 2416 |
| 2420 | 2417 |
| 2421 int LoopChoiceNode::EatsAtLeast(int still_to_find, | 2418 int LoopChoiceNode::EatsAtLeast(int still_to_find, |
| 2422 int recursion_depth, | 2419 int budget, |
| 2423 bool not_at_start) { | 2420 bool not_at_start) { |
| 2424 return EatsAtLeastHelper(still_to_find, | 2421 return EatsAtLeastHelper(still_to_find, |
| 2425 recursion_depth, | 2422 budget - 1, |
| 2426 loop_node_, | 2423 loop_node_, |
| 2427 not_at_start); | 2424 not_at_start); |
| 2428 } | 2425 } |
| 2429 | 2426 |
| 2430 | 2427 |
| 2431 int ChoiceNode::EatsAtLeast(int still_to_find, | 2428 int ChoiceNode::EatsAtLeast(int still_to_find, |
| 2432 int recursion_depth, | 2429 int budget, |
| 2433 bool not_at_start) { | 2430 bool not_at_start) { |
| 2434 return EatsAtLeastHelper(still_to_find, | 2431 return EatsAtLeastHelper(still_to_find, |
| 2435 recursion_depth, | 2432 budget, |
| 2436 NULL, | 2433 NULL, |
| 2437 not_at_start); | 2434 not_at_start); |
| 2438 } | 2435 } |
| 2439 | 2436 |
| 2440 | 2437 |
| 2441 // Takes the left-most 1-bit and smears it out, setting all bits to its right. | 2438 // Takes the left-most 1-bit and smears it out, setting all bits to its right. |
| 2442 static inline uint32_t SmearBitsRight(uint32_t v) { | 2439 static inline uint32_t SmearBitsRight(uint32_t v) { |
| 2443 v |= v >> 1; | 2440 v |= v >> 1; |
| 2444 v |= v >> 2; | 2441 v |= v >> 2; |
| 2445 v |= v >> 4; | 2442 v |= v >> 4; |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2981 if (body_can_be_zero_length_ || info()->visited) return; | 2978 if (body_can_be_zero_length_ || info()->visited) return; |
| 2982 VisitMarker marker(info()); | 2979 VisitMarker marker(info()); |
| 2983 return ChoiceNode::GetQuickCheckDetails(details, | 2980 return ChoiceNode::GetQuickCheckDetails(details, |
| 2984 compiler, | 2981 compiler, |
| 2985 characters_filled_in, | 2982 characters_filled_in, |
| 2986 not_at_start); | 2983 not_at_start); |
| 2987 } | 2984 } |
| 2988 | 2985 |
| 2989 | 2986 |
| 2990 void LoopChoiceNode::FillInBMInfo(int offset, | 2987 void LoopChoiceNode::FillInBMInfo(int offset, |
| 2991 int recursion_depth, | |
| 2992 int budget, | 2988 int budget, |
| 2993 BoyerMooreLookahead* bm, | 2989 BoyerMooreLookahead* bm, |
| 2994 bool not_at_start) { | 2990 bool not_at_start) { |
| 2995 if (body_can_be_zero_length_ || | 2991 if (body_can_be_zero_length_ || budget <= 0) { |
| 2996 recursion_depth > RegExpCompiler::kMaxRecursion || | |
| 2997 budget <= 0) { | |
| 2998 bm->SetRest(offset); | 2992 bm->SetRest(offset); |
| 2999 SaveBMInfo(bm, not_at_start, offset); | 2993 SaveBMInfo(bm, not_at_start, offset); |
| 3000 return; | 2994 return; |
| 3001 } | 2995 } |
| 3002 ChoiceNode::FillInBMInfo( | 2996 ChoiceNode::FillInBMInfo(offset, budget - 1, bm, not_at_start); |
| 3003 offset, recursion_depth + 1, budget - 1, bm, not_at_start); | |
| 3004 SaveBMInfo(bm, not_at_start, offset); | 2997 SaveBMInfo(bm, not_at_start, offset); |
| 3005 } | 2998 } |
| 3006 | 2999 |
| 3007 | 3000 |
| 3008 void ChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details, | 3001 void ChoiceNode::GetQuickCheckDetails(QuickCheckDetails* details, |
| 3009 RegExpCompiler* compiler, | 3002 RegExpCompiler* compiler, |
| 3010 int characters_filled_in, | 3003 int characters_filled_in, |
| 3011 bool not_at_start) { | 3004 bool not_at_start) { |
| 3012 not_at_start = (not_at_start || not_at_start_); | 3005 not_at_start = (not_at_start || not_at_start_); |
| 3013 int choice_count = alternatives_->length(); | 3006 int choice_count = alternatives_->length(); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3090 | 3083 |
| 3091 | 3084 |
| 3092 // Emit the code to handle \b and \B (word-boundary or non-word-boundary). | 3085 // Emit the code to handle \b and \B (word-boundary or non-word-boundary). |
| 3093 void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) { | 3086 void AssertionNode::EmitBoundaryCheck(RegExpCompiler* compiler, Trace* trace) { |
| 3094 RegExpMacroAssembler* assembler = compiler->macro_assembler(); | 3087 RegExpMacroAssembler* assembler = compiler->macro_assembler(); |
| 3095 Trace::TriBool next_is_word_character = Trace::UNKNOWN; | 3088 Trace::TriBool next_is_word_character = Trace::UNKNOWN; |
| 3096 bool not_at_start = (trace->at_start() == Trace::FALSE); | 3089 bool not_at_start = (trace->at_start() == Trace::FALSE); |
| 3097 BoyerMooreLookahead* lookahead = bm_info(not_at_start); | 3090 BoyerMooreLookahead* lookahead = bm_info(not_at_start); |
| 3098 if (lookahead == NULL) { | 3091 if (lookahead == NULL) { |
| 3099 int eats_at_least = | 3092 int eats_at_least = |
| 3100 Min(kMaxLookaheadForBoyerMoore, | 3093 Min(kMaxLookaheadForBoyerMoore, EatsAtLeast(kMaxLookaheadForBoyerMoore, |
| 3101 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); | 3094 kFillInBMBudget, |
| 3095 not_at_start)); |
| 3102 if (eats_at_least >= 1) { | 3096 if (eats_at_least >= 1) { |
| 3103 BoyerMooreLookahead* bm = | 3097 BoyerMooreLookahead* bm = |
| 3104 new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone()); | 3098 new(zone()) BoyerMooreLookahead(eats_at_least, compiler, zone()); |
| 3105 FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); | 3099 FillInBMInfo(0, kFillInBMBudget, bm, not_at_start); |
| 3106 if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; | 3100 if (bm->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; |
| 3107 if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE; | 3101 if (bm->at(0)->is_word()) next_is_word_character = Trace::TRUE; |
| 3108 } | 3102 } |
| 3109 } else { | 3103 } else { |
| 3110 if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; | 3104 if (lookahead->at(0)->is_non_word()) next_is_word_character = Trace::FALSE; |
| 3111 if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE; | 3105 if (lookahead->at(0)->is_word()) next_is_word_character = Trace::TRUE; |
| 3112 } | 3106 } |
| 3113 bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY); | 3107 bool at_boundary = (type_ == AssertionNode::AT_BOUNDARY); |
| 3114 if (next_is_word_character == Trace::UNKNOWN) { | 3108 if (next_is_word_character == Trace::UNKNOWN) { |
| 3115 Label before_non_word; | 3109 Label before_non_word; |
| (...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4027 // At this point we know that we are at a non-greedy loop that will eat | 4021 // At this point we know that we are at a non-greedy loop that will eat |
| 4028 // any character one at a time. Any non-anchored regexp has such a | 4022 // any character one at a time. Any non-anchored regexp has such a |
| 4029 // loop prepended to it in order to find where it starts. We look for | 4023 // loop prepended to it in order to find where it starts. We look for |
| 4030 // a pattern of the form ...abc... where we can look 6 characters ahead | 4024 // a pattern of the form ...abc... where we can look 6 characters ahead |
| 4031 // and step forwards 3 if the character is not one of abc. Abc need | 4025 // and step forwards 3 if the character is not one of abc. Abc need |
| 4032 // not be atoms, they can be any reasonably limited character class or | 4026 // not be atoms, they can be any reasonably limited character class or |
| 4033 // small alternation. | 4027 // small alternation. |
| 4034 ASSERT(trace->is_trivial()); // This is the case on LoopChoiceNodes. | 4028 ASSERT(trace->is_trivial()); // This is the case on LoopChoiceNodes. |
| 4035 BoyerMooreLookahead* lookahead = bm_info(not_at_start); | 4029 BoyerMooreLookahead* lookahead = bm_info(not_at_start); |
| 4036 if (lookahead == NULL) { | 4030 if (lookahead == NULL) { |
| 4037 eats_at_least = | 4031 eats_at_least = Min(kMaxLookaheadForBoyerMoore, |
| 4038 Min(kMaxLookaheadForBoyerMoore, | 4032 EatsAtLeast(kMaxLookaheadForBoyerMoore, |
| 4039 EatsAtLeast(kMaxLookaheadForBoyerMoore, 0, not_at_start)); | 4033 kFillInBMBudget, |
| 4034 not_at_start)); |
| 4040 if (eats_at_least >= 1) { | 4035 if (eats_at_least >= 1) { |
| 4041 BoyerMooreLookahead* bm = | 4036 BoyerMooreLookahead* bm = |
| 4042 new(zone()) BoyerMooreLookahead(eats_at_least, | 4037 new(zone()) BoyerMooreLookahead(eats_at_least, |
| 4043 compiler, | 4038 compiler, |
| 4044 zone()); | 4039 zone()); |
| 4045 GuardedAlternative alt0 = alternatives_->at(0); | 4040 GuardedAlternative alt0 = alternatives_->at(0); |
| 4046 alt0.node()->FillInBMInfo(0, 0, kFillInBMBudget, bm, not_at_start); | 4041 alt0.node()->FillInBMInfo(0, kFillInBMBudget, bm, not_at_start); |
| 4047 skip_was_emitted = bm->EmitSkipInstructions(macro_assembler); | 4042 skip_was_emitted = bm->EmitSkipInstructions(macro_assembler); |
| 4048 } | 4043 } |
| 4049 } else { | 4044 } else { |
| 4050 skip_was_emitted = lookahead->EmitSkipInstructions(macro_assembler); | 4045 skip_was_emitted = lookahead->EmitSkipInstructions(macro_assembler); |
| 4051 } | 4046 } |
| 4052 } | 4047 } |
| 4053 } | 4048 } |
| 4054 } | 4049 } |
| 4055 | 4050 |
| 4056 if (eats_at_least == kEatsAtLeastNotYetInitialized) { | 4051 if (eats_at_least == kEatsAtLeastNotYetInitialized) { |
| 4057 // Save some time by looking at most one machine word ahead. | 4052 // Save some time by looking at most one machine word ahead. |
| 4058 eats_at_least = EatsAtLeast(compiler->ascii() ? 4 : 2, 0, not_at_start); | 4053 eats_at_least = |
| 4054 EatsAtLeast(compiler->ascii() ? 4 : 2, kFillInBMBudget, not_at_start); |
| 4059 } | 4055 } |
| 4060 int preload_characters = CalculatePreloadCharacters(compiler, eats_at_least); | 4056 int preload_characters = CalculatePreloadCharacters(compiler, eats_at_least); |
| 4061 | 4057 |
| 4062 bool preload_is_current = !skip_was_emitted && | 4058 bool preload_is_current = !skip_was_emitted && |
| 4063 (current_trace->characters_preloaded() == preload_characters); | 4059 (current_trace->characters_preloaded() == preload_characters); |
| 4064 bool preload_has_checked_bounds = preload_is_current; | 4060 bool preload_has_checked_bounds = preload_is_current; |
| 4065 | 4061 |
| 4066 AlternativeGenerationList alt_gens(choice_count, zone()); | 4062 AlternativeGenerationList alt_gens(choice_count, zone()); |
| 4067 | 4063 |
| 4068 // For now we just call all choices one after the other. The idea ultimately | 4064 // For now we just call all choices one after the other. The idea ultimately |
| (...skipping 1735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5804 EnsureAnalyzed(that->on_success()); | 5800 EnsureAnalyzed(that->on_success()); |
| 5805 } | 5801 } |
| 5806 | 5802 |
| 5807 | 5803 |
| 5808 void Analysis::VisitAssertion(AssertionNode* that) { | 5804 void Analysis::VisitAssertion(AssertionNode* that) { |
| 5809 EnsureAnalyzed(that->on_success()); | 5805 EnsureAnalyzed(that->on_success()); |
| 5810 } | 5806 } |
| 5811 | 5807 |
| 5812 | 5808 |
| 5813 void BackReferenceNode::FillInBMInfo(int offset, | 5809 void BackReferenceNode::FillInBMInfo(int offset, |
| 5814 int recursion_depth, | |
| 5815 int budget, | 5810 int budget, |
| 5816 BoyerMooreLookahead* bm, | 5811 BoyerMooreLookahead* bm, |
| 5817 bool not_at_start) { | 5812 bool not_at_start) { |
| 5818 // Working out the set of characters that a backreference can match is too | 5813 // Working out the set of characters that a backreference can match is too |
| 5819 // hard, so we just say that any character can match. | 5814 // hard, so we just say that any character can match. |
| 5820 bm->SetRest(offset); | 5815 bm->SetRest(offset); |
| 5821 SaveBMInfo(bm, not_at_start, offset); | 5816 SaveBMInfo(bm, not_at_start, offset); |
| 5822 } | 5817 } |
| 5823 | 5818 |
| 5824 | 5819 |
| 5825 STATIC_ASSERT(BoyerMoorePositionInfo::kMapSize == | 5820 STATIC_ASSERT(BoyerMoorePositionInfo::kMapSize == |
| 5826 RegExpMacroAssembler::kTableSize); | 5821 RegExpMacroAssembler::kTableSize); |
| 5827 | 5822 |
| 5828 | 5823 |
| 5829 void ChoiceNode::FillInBMInfo(int offset, | 5824 void ChoiceNode::FillInBMInfo(int offset, |
| 5830 int recursion_depth, | |
| 5831 int budget, | 5825 int budget, |
| 5832 BoyerMooreLookahead* bm, | 5826 BoyerMooreLookahead* bm, |
| 5833 bool not_at_start) { | 5827 bool not_at_start) { |
| 5834 ZoneList<GuardedAlternative>* alts = alternatives(); | 5828 ZoneList<GuardedAlternative>* alts = alternatives(); |
| 5835 budget = (budget - 1) / alts->length(); | 5829 budget = (budget - 1) / alts->length(); |
| 5836 for (int i = 0; i < alts->length(); i++) { | 5830 for (int i = 0; i < alts->length(); i++) { |
| 5837 GuardedAlternative& alt = alts->at(i); | 5831 GuardedAlternative& alt = alts->at(i); |
| 5838 if (alt.guards() != NULL && alt.guards()->length() != 0) { | 5832 if (alt.guards() != NULL && alt.guards()->length() != 0) { |
| 5839 bm->SetRest(offset); // Give up trying to fill in info. | 5833 bm->SetRest(offset); // Give up trying to fill in info. |
| 5840 SaveBMInfo(bm, not_at_start, offset); | 5834 SaveBMInfo(bm, not_at_start, offset); |
| 5841 return; | 5835 return; |
| 5842 } | 5836 } |
| 5843 alt.node()->FillInBMInfo( | 5837 alt.node()->FillInBMInfo(offset, budget, bm, not_at_start); |
| 5844 offset, recursion_depth + 1, budget, bm, not_at_start); | |
| 5845 } | 5838 } |
| 5846 SaveBMInfo(bm, not_at_start, offset); | 5839 SaveBMInfo(bm, not_at_start, offset); |
| 5847 } | 5840 } |
| 5848 | 5841 |
| 5849 | 5842 |
| 5850 void TextNode::FillInBMInfo(int initial_offset, | 5843 void TextNode::FillInBMInfo(int initial_offset, |
| 5851 int recursion_depth, | |
| 5852 int budget, | 5844 int budget, |
| 5853 BoyerMooreLookahead* bm, | 5845 BoyerMooreLookahead* bm, |
| 5854 bool not_at_start) { | 5846 bool not_at_start) { |
| 5855 if (initial_offset >= bm->length()) return; | 5847 if (initial_offset >= bm->length()) return; |
| 5856 int offset = initial_offset; | 5848 int offset = initial_offset; |
| 5857 int max_char = bm->max_char(); | 5849 int max_char = bm->max_char(); |
| 5858 for (int i = 0; i < elements()->length(); i++) { | 5850 for (int i = 0; i < elements()->length(); i++) { |
| 5859 if (offset >= bm->length()) { | 5851 if (offset >= bm->length()) { |
| 5860 if (initial_offset == 0) set_bm_info(not_at_start, bm); | 5852 if (initial_offset == 0) set_bm_info(not_at_start, bm); |
| 5861 return; | 5853 return; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5898 } | 5890 } |
| 5899 } | 5891 } |
| 5900 offset++; | 5892 offset++; |
| 5901 } | 5893 } |
| 5902 } | 5894 } |
| 5903 if (offset >= bm->length()) { | 5895 if (offset >= bm->length()) { |
| 5904 if (initial_offset == 0) set_bm_info(not_at_start, bm); | 5896 if (initial_offset == 0) set_bm_info(not_at_start, bm); |
| 5905 return; | 5897 return; |
| 5906 } | 5898 } |
| 5907 on_success()->FillInBMInfo(offset, | 5899 on_success()->FillInBMInfo(offset, |
| 5908 recursion_depth + 1, | |
| 5909 budget - 1, | 5900 budget - 1, |
| 5910 bm, | 5901 bm, |
| 5911 true); // Not at start after a text node. | 5902 true); // Not at start after a text node. |
| 5912 if (initial_offset == 0) set_bm_info(not_at_start, bm); | 5903 if (initial_offset == 0) set_bm_info(not_at_start, bm); |
| 5913 } | 5904 } |
| 5914 | 5905 |
| 5915 | 5906 |
| 5916 // ------------------------------------------------------------------- | 5907 // ------------------------------------------------------------------- |
| 5917 // Dispatch table construction | 5908 // Dispatch table construction |
| 5918 | 5909 |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6150 } | 6141 } |
| 6151 | 6142 |
| 6152 return compiler.Assemble(¯o_assembler, | 6143 return compiler.Assemble(¯o_assembler, |
| 6153 node, | 6144 node, |
| 6154 data->capture_count, | 6145 data->capture_count, |
| 6155 pattern); | 6146 pattern); |
| 6156 } | 6147 } |
| 6157 | 6148 |
| 6158 | 6149 |
| 6159 }} // namespace v8::internal | 6150 }} // namespace v8::internal |
| OLD | NEW |