| 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;
|
| }
|
|
|
|
|
|
|