Reviewers: Christian Plesner Hansen,

Description:
Generate code for choice nodes.

Please review this at http://codereview.chromium.org/10947

SVN Base: http://v8.googlecode.com/svn/branches/experimental/regexp2000/

Affected files:
   M     src/jsregexp.h
   M     src/jsregexp.cc


Index: src/jsregexp.h
===================================================================
--- src/jsregexp.h      (revision 753)
+++ src/jsregexp.h      (working copy)
@@ -404,7 +404,7 @@
    // Until the implementation is complete we will return true for success  
and
    // false for failure.
    bool GoTo(RegExpCompiler* compiler);
-  void EmitAddress(RegExpCompiler* compiler);
+  Label* GetLabel();
    // Until the implementation is complete we will return true for success  
and
    // false for failure.
    virtual bool Emit(RegExpCompiler* compiler) = 0;
@@ -589,6 +589,9 @@
    bool visited() { return visited_; }
    void set_visited(bool value) { visited_ = value; }
   private:
+  void GenerateGuard(RegExpCompiler* compiler,
+                     Guard *guard,
+                     Label* on_failure);
    RegExpNode* on_failure_;
    ZoneList<GuardedAlternative>* choices_;
    DispatchTable table_;
Index: src/jsregexp.cc
===================================================================
--- src/jsregexp.cc     (revision 753)
+++ src/jsregexp.cc     (working copy)
@@ -866,8 +866,8 @@
  }


-void RegExpNode::EmitAddress(RegExpCompiler* compiler) {
-  compiler->macro_assembler()->EmitOrLink(&label);
+Label* RegExpNode::GetLabel() {
+  return &label;
  }


@@ -963,9 +963,50 @@
  // Emit code.


+void ChoiceNode::GenerateGuard(RegExpCompiler* compiler,
+                               Guard *guard,
+                               Label* on_failure) {
+
+}
+
+
  bool ChoiceNode::Emit(RegExpCompiler* compiler) {
-  // TODO(erikcorry): Implement this.
-  return false;
+  int choice_count = choices_->length();
+  RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
+  // For now we just call all choices one after the other.  The idea  
ultimately
+  // is to use the Dispatch table to try only the relevant ones.
+  for (int i = 0; i < choice_count; i++) {
+    GuardedAlternative alternative = (*choices_)[i];
+    Label after;
+    Label* next_alternative;
+    if (i < choice_count - 1) {
+      next_alternative = &after;
+    } else {
+      next_alternative = on_failure_->GetLabel();
+    }
+    ZoneList<Guard*>* guards = alternative.guards();
+    if (guards != NULL) {
+      int guard_count = guards->length();
+      for (int j = 0; j < guard_count; j++) {
+        GenerateGuard(compiler, (*guards)[i], next_alternative);
+      }
+    }
+    macro_assembler->PushBacktrack(next_alternative);
+    if (!alternative.node()->Emit(compiler)) {
+      after.Unuse();
+      if (next_alternative != &after) {
+        next_alternative->Unuse();
+      }
+      return false;
+    }
+    if (i < choice_count - 1) {
+      macro_assembler->Bind(&after);
+    } else {
+      after.Unuse();
+    }
+  }
+  compiler->AddWork(on_failure_);
+  return true;
  }





--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to