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

Side by Side Diff: src/jsregexp.h

Issue 10944: Restructure analysis (Closed)
Patch Set: Created 12 years, 1 month 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/ast.cc ('k') | src/jsregexp.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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 void set_to(uc16 value) { to_ = value; } 159 void set_to(uc16 value) { to_ = value; }
160 bool is_valid() { return from_ <= to_; } 160 bool is_valid() { return from_ <= to_; }
161 bool IsSingleton() { return (from_ == to_); } 161 bool IsSingleton() { return (from_ == to_); }
162 private: 162 private:
163 uc16 from_; 163 uc16 from_;
164 uc16 to_; 164 uc16 to_;
165 }; 165 };
166 166
167 167
168 template <typename Node, class Callback> 168 template <typename Node, class Callback>
169 static void DoForEach(Node* node, Callback callback); 169 static void DoForEach(Node* node, Callback* callback);
170 170
171 171
172 // A zone splay tree. The config type parameter encapsulates the 172 // A zone splay tree. The config type parameter encapsulates the
173 // different configurations of a concrete splay tree: 173 // different configurations of a concrete splay tree:
174 // 174 //
175 // typedef Key: the key type 175 // typedef Key: the key type
176 // typedef Value: the value type 176 // typedef Value: the value type
177 // static const kNoKey: the dummy key used when no key is set 177 // static const kNoKey: the dummy key used when no key is set
178 // static const kNoValue: the dummy value used to initialize nodes 178 // static const kNoValue: the dummy value used to initialize nodes
179 // int (Compare)(Key& a, Key& b) -> {-1, 0, 1}: comparison function 179 // int (Compare)(Key& a, Key& b) -> {-1, 0, 1}: comparison function
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 Locator() : node_(NULL) { } 251 Locator() : node_(NULL) { }
252 const Key& key() { return node_->key_; } 252 const Key& key() { return node_->key_; }
253 Value& value() { return node_->value_; } 253 Value& value() { return node_->value_; }
254 void set_value(const Value& value) { node_->value_ = value; } 254 void set_value(const Value& value) { node_->value_ = value; }
255 inline void bind(Node* node) { node_ = node; } 255 inline void bind(Node* node) { node_ = node; }
256 private: 256 private:
257 Node* node_; 257 Node* node_;
258 }; 258 };
259 259
260 template <class Callback> 260 template <class Callback>
261 void ForEach(Callback c) { 261 void ForEach(Callback* c) {
262 DoForEach<typename ZoneSplayTree<Config>::Node, Callback>(root_, c); 262 DoForEach<typename ZoneSplayTree<Config>::Node, Callback>(root_, c);
263 } 263 }
264 264
265 private: 265 private:
266 Node* root_; 266 Node* root_;
267 }; 267 };
268 268
269 269
270 // A set of unsigned integers that behaves especially well on small 270 // A set of unsigned integers that behaves especially well on small
271 // integers (< 32). May do zone-allocation. 271 // integers (< 32). May do zone-allocation.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 else 330 else
331 return 1; 331 return 1;
332 } 332 }
333 }; 333 };
334 334
335 void AddRange(CharacterRange range, int value); 335 void AddRange(CharacterRange range, int value);
336 OutSet* Get(uc16 value); 336 OutSet* Get(uc16 value);
337 void Dump(); 337 void Dump();
338 338
339 template <typename Callback> 339 template <typename Callback>
340 void ForEach(Callback callback) { return tree()->ForEach(callback); } 340 void ForEach(Callback* callback) { return tree()->ForEach(callback); }
341 private: 341 private:
342 // There can't be a static empty set since it allocates its 342 // There can't be a static empty set since it allocates its
343 // successors in a zone and caches them. 343 // successors in a zone and caches them.
344 OutSet* empty() { return &empty_; } 344 OutSet* empty() { return &empty_; }
345 OutSet empty_; 345 OutSet empty_;
346 ZoneSplayTree<Config>* tree() { return &tree_; } 346 ZoneSplayTree<Config>* tree() { return &tree_; }
347 ZoneSplayTree<Config> tree_; 347 ZoneSplayTree<Config> tree_;
348 }; 348 };
349 349
350 350
351 #define FOR_EACH_NODE_TYPE(VISIT) \ 351 #define FOR_EACH_NODE_TYPE(VISIT) \
352 VISIT(End) \ 352 VISIT(End) \
353 VISIT(Atom) \ 353 VISIT(Atom) \
354 VISIT(Action) \ 354 VISIT(Action) \
355 VISIT(Choice) \ 355 VISIT(Choice) \
356 VISIT(Backreference) \ 356 VISIT(Backreference) \
357 VISIT(CharacterClass) 357 VISIT(CharacterClass)
358 358
359 359
360 class NodeInfo {
361 public:
362 NodeInfo()
363 : being_analyzed(false),
364 been_analyzed(false),
365 propagate_word(false),
366 propagate_line(false) { }
367 bool being_analyzed: 1;
368 bool been_analyzed: 1;
369 bool propagate_word: 1;
370 bool propagate_line: 1;
371 };
372
373
374 STATIC_CHECK(sizeof(NodeInfo) <= sizeof(int)); // NOLINT
375
376
360 class RegExpNode: public ZoneObject { 377 class RegExpNode: public ZoneObject {
361 public: 378 public:
362 virtual ~RegExpNode() { } 379 virtual ~RegExpNode() { }
363 virtual void Accept(NodeVisitor* visitor) = 0; 380 virtual void Accept(NodeVisitor* visitor) = 0;
364 // Generates a goto to this node or actually generates the code at this point. 381 // Generates a goto to this node or actually generates the code at this point.
365 void GoTo(RegExpCompiler* compiler); 382 void GoTo(RegExpCompiler* compiler);
366 void EmitAddress(RegExpCompiler* compiler); 383 void EmitAddress(RegExpCompiler* compiler);
367 virtual void Emit(RegExpCompiler* compiler) = 0; 384 virtual void Emit(RegExpCompiler* compiler) = 0;
385 NodeInfo* info() { return &info_; }
386 virtual bool IsBacktrack() { return false; }
368 private: 387 private:
369 Label label; 388 Label label;
389 NodeInfo info_;
370 }; 390 };
371 391
372 392
373 class SeqRegExpNode: public RegExpNode { 393 class SeqRegExpNode: public RegExpNode {
374 public: 394 public:
375 explicit SeqRegExpNode(RegExpNode* on_success) 395 explicit SeqRegExpNode(RegExpNode* on_success)
376 : on_success_(on_success) { } 396 : on_success_(on_success) { }
377 RegExpNode* on_success() { return on_success_; } 397 RegExpNode* on_success() { return on_success_; }
378 virtual void Emit(RegExpCompiler* compiler) { UNREACHABLE(); } 398 virtual void Emit(RegExpCompiler* compiler) { UNREACHABLE(); }
379 private: 399 private:
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 private: 503 private:
484 RegExpNode* on_failure_; 504 RegExpNode* on_failure_;
485 ZoneList<CharacterRange>* ranges_; 505 ZoneList<CharacterRange>* ranges_;
486 bool is_negated_; 506 bool is_negated_;
487 }; 507 };
488 508
489 509
490 class EndNode: public RegExpNode { 510 class EndNode: public RegExpNode {
491 public: 511 public:
492 enum Action { ACCEPT, BACKTRACK }; 512 enum Action { ACCEPT, BACKTRACK };
513 explicit EndNode(Action action) : action_(action) { }
493 virtual void Accept(NodeVisitor* visitor); 514 virtual void Accept(NodeVisitor* visitor);
494 static EndNode* GetAccept() { return &kAccept; }
495 static EndNode* GetBacktrack() { return &kBacktrack; }
496 virtual void Emit(RegExpCompiler* compiler) { UNREACHABLE(); } 515 virtual void Emit(RegExpCompiler* compiler) { UNREACHABLE(); }
516 virtual bool IsBacktrack() { return action_ == BACKTRACK; }
497 private: 517 private:
498 explicit EndNode(Action action) : action_(action) { }
499 Action action_; 518 Action action_;
500 static EndNode kAccept;
501 static EndNode kBacktrack;
502 }; 519 };
503 520
504 521
505 class Guard: public ZoneObject { 522 class Guard: public ZoneObject {
506 public: 523 public:
507 enum Relation { LT, GEQ }; 524 enum Relation { LT, GEQ };
508 Guard(int reg, Relation op, int value) 525 Guard(int reg, Relation op, int value)
509 : reg_(reg), 526 : reg_(reg),
510 op_(op), 527 op_(op),
511 value_(value) { } 528 value_(value) { }
(...skipping 16 matching lines...) Expand all
528 private: 545 private:
529 RegExpNode* node_; 546 RegExpNode* node_;
530 ZoneList<Guard*>* guards_; 547 ZoneList<Guard*>* guards_;
531 }; 548 };
532 549
533 550
534 class ChoiceNode: public RegExpNode { 551 class ChoiceNode: public RegExpNode {
535 public: 552 public:
536 explicit ChoiceNode(int expected_size, RegExpNode* on_failure) 553 explicit ChoiceNode(int expected_size, RegExpNode* on_failure)
537 : on_failure_(on_failure), 554 : on_failure_(on_failure),
538 choices_(new ZoneList<GuardedAlternative>(expected_size)), 555 alternatives_(new ZoneList<GuardedAlternative>(expected_size)),
539 visited_(false) { } 556 table_calculated_(false),
557 being_calculated_(false) { }
540 virtual void Accept(NodeVisitor* visitor); 558 virtual void Accept(NodeVisitor* visitor);
541 void AddChild(GuardedAlternative node) { choices()->Add(node); } 559 void AddAlternative(GuardedAlternative node) { alternatives()->Add(node); }
542 ZoneList<GuardedAlternative>* choices() { return choices_; } 560 ZoneList<GuardedAlternative>* alternatives() { return alternatives_; }
543 DispatchTable* table() { return &table_; } 561 DispatchTable* table() { return &table_; }
544 RegExpNode* on_failure() { return on_failure_; } 562 RegExpNode* on_failure() { return on_failure_; }
545 virtual void Emit(RegExpCompiler* compiler); 563 virtual void Emit(RegExpCompiler* compiler);
546 bool visited() { return visited_; } 564 bool table_calculated() { return table_calculated_; }
547 void set_visited(bool value) { visited_ = value; } 565 void set_table_calculated(bool b) { table_calculated_ = b; }
566 bool being_calculated() { return being_calculated_; }
567 void set_being_calculated(bool b) { being_calculated_ = b; }
548 private: 568 private:
549 RegExpNode* on_failure_; 569 RegExpNode* on_failure_;
550 ZoneList<GuardedAlternative>* choices_; 570 ZoneList<GuardedAlternative>* alternatives_;
551 DispatchTable table_; 571 DispatchTable table_;
552 bool visited_; 572 bool table_calculated_;
573 bool being_calculated_;
553 }; 574 };
554 575
555 576
577 class NodeVisitor {
578 public:
579 virtual ~NodeVisitor() { }
580 #define DECLARE_VISIT(Type) \
581 virtual void Visit##Type(Type##Node* that) = 0;
582 FOR_EACH_NODE_TYPE(DECLARE_VISIT)
583 #undef DECLARE_VISIT
584 };
585
586
587 // Node visitor used to add the start set of the alternatives to the
588 // dispatch table of a choice node.
589 class DispatchTableConstructor: public NodeVisitor {
590 public:
591 explicit DispatchTableConstructor(DispatchTable* table)
592 : table_(table),
593 choice_index_(-1) { }
594
595 void BuildTable(ChoiceNode* node);
596
597 void AddRange(CharacterRange range) {
598 table()->AddRange(range, choice_index_);
599 }
600
601 void AddInverse(ZoneList<CharacterRange>* ranges);
602
603 #define DECLARE_VISIT(Type) \
604 virtual void Visit##Type(Type##Node* that);
605 FOR_EACH_NODE_TYPE(DECLARE_VISIT)
606 #undef DECLARE_VISIT
607
608 DispatchTable* table() { return table_; }
609 void set_choice_index(int value) { choice_index_ = value; }
610
611 protected:
612 DispatchTable *table_;
613 int choice_index_;
614 };
615
616
617 class Analysis: public NodeVisitor {
618 public:
619 void EnsureAnalyzed(RegExpNode* node);
620
621 #define DECLARE_VISIT(Type) \
622 virtual void Visit##Type(Type##Node* that);
623 FOR_EACH_NODE_TYPE(DECLARE_VISIT)
624 #undef DECLARE_VISIT
625 };
626
627
556 struct RegExpParseResult { 628 struct RegExpParseResult {
557 RegExpTree* tree; 629 RegExpTree* tree;
558 bool has_character_escapes; 630 bool has_character_escapes;
559 Handle<String> error; 631 Handle<String> error;
560 int capture_count; 632 int capture_count;
561 }; 633 };
562 634
563 635
564 class RegExpEngine: public AllStatic { 636 class RegExpEngine: public AllStatic {
565 public: 637 public:
566 static RegExpNode* Compile(RegExpParseResult* input); 638 static RegExpNode* Compile(RegExpParseResult* input);
567 static void DotPrint(const char* label, RegExpNode* node); 639 static void DotPrint(const char* label, RegExpNode* node);
568 }; 640 };
569 641
570 642
571 class RegExpCompiler;
572
573
574 } } // namespace v8::internal 643 } } // namespace v8::internal
575 644
576 #endif // V8_JSREGEXP_H_ 645 #endif // V8_JSREGEXP_H_
OLDNEW
« no previous file with comments | « src/ast.cc ('k') | src/jsregexp.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698