Index: src/jsregexp.cc |
diff --git a/src/jsregexp.cc b/src/jsregexp.cc |
index 18004e3b59e0ea02020d4c27a4b730b4463f6274..82d824ab0961846b18aaeb4c6a7eef0c907d8ad4 100644 |
--- a/src/jsregexp.cc |
+++ b/src/jsregexp.cc |
@@ -12,6 +12,7 @@ |
#include "src/factory.h" |
#include "src/jsregexp-inl.h" |
#include "src/jsregexp.h" |
+#include "src/ostreams.h" |
#include "src/parser.h" |
#include "src/regexp-macro-assembler.h" |
#include "src/regexp-macro-assembler-irregexp.h" |
@@ -19,7 +20,6 @@ |
#include "src/regexp-stack.h" |
#include "src/runtime.h" |
#include "src/string-search.h" |
-#include "src/string-stream.h" |
#ifndef V8_INTERPRETED_REGEXP |
#if V8_TARGET_ARCH_IA32 |
@@ -1133,8 +1133,8 @@ RegExpEngine::CompilationResult RegExpCompiler::Assemble( |
#ifdef DEBUG |
if (FLAG_print_code) { |
CodeTracer::Scope trace_scope(heap->isolate()->GetCodeTracer()); |
- Handle<Code>::cast(code)->Disassemble(pattern->ToCString().get(), |
- trace_scope.file()); |
+ OFStream os(trace_scope.file()); |
+ Handle<Code>::cast(code)->Disassemble(pattern->ToCString().get(), os); |
} |
if (FLAG_trace_regexp_assembler) { |
delete macro_assembler_; |
@@ -4323,44 +4323,41 @@ void BackReferenceNode::Emit(RegExpCompiler* compiler, Trace* trace) { |
class DotPrinter: public NodeVisitor { |
public: |
- explicit DotPrinter(bool ignore_case) |
- : ignore_case_(ignore_case), |
- stream_(&alloc_) { } |
+ DotPrinter(OStream& os, bool ignore_case) // NOLINT |
+ : os_(os), |
+ ignore_case_(ignore_case) {} |
void PrintNode(const char* label, RegExpNode* node); |
void Visit(RegExpNode* node); |
void PrintAttributes(RegExpNode* from); |
- StringStream* stream() { return &stream_; } |
void PrintOnFailure(RegExpNode* from, RegExpNode* to); |
#define DECLARE_VISIT(Type) \ |
virtual void Visit##Type(Type##Node* that); |
FOR_EACH_NODE_TYPE(DECLARE_VISIT) |
#undef DECLARE_VISIT |
private: |
+ OStream& os_; |
bool ignore_case_; |
- HeapStringAllocator alloc_; |
- StringStream stream_; |
}; |
void DotPrinter::PrintNode(const char* label, RegExpNode* node) { |
- stream()->Add("digraph G {\n graph [label=\""); |
+ os_ << "digraph G {\n graph [label=\""; |
for (int i = 0; label[i]; i++) { |
switch (label[i]) { |
case '\\': |
- stream()->Add("\\\\"); |
+ os_ << "\\\\"; |
break; |
case '"': |
- stream()->Add("\""); |
+ os_ << "\""; |
break; |
default: |
- stream()->Put(label[i]); |
+ os_ << label[i]; |
break; |
} |
} |
- stream()->Add("\"];\n"); |
+ os_ << "\"];\n"; |
Visit(node); |
- stream()->Add("}\n"); |
- printf("%s", stream()->ToCString().get()); |
+ os_ << "}" << endl; |
} |
@@ -4372,97 +4369,95 @@ void DotPrinter::Visit(RegExpNode* node) { |
void DotPrinter::PrintOnFailure(RegExpNode* from, RegExpNode* on_failure) { |
- stream()->Add(" n%p -> n%p [style=dotted];\n", from, on_failure); |
+ os_ << " n" << from << " -> n" << on_failure << " [style=dotted];\n"; |
Visit(on_failure); |
} |
class TableEntryBodyPrinter { |
public: |
- TableEntryBodyPrinter(StringStream* stream, ChoiceNode* choice) |
- : stream_(stream), choice_(choice) { } |
+ TableEntryBodyPrinter(OStream& os, ChoiceNode* choice) // NOLINT |
+ : os_(os), |
+ choice_(choice) {} |
void Call(uc16 from, DispatchTable::Entry entry) { |
OutSet* out_set = entry.out_set(); |
for (unsigned i = 0; i < OutSet::kFirstLimit; i++) { |
if (out_set->Get(i)) { |
- stream()->Add(" n%p:s%io%i -> n%p;\n", |
- choice(), |
- from, |
- i, |
- choice()->alternatives()->at(i).node()); |
+ os_ << " n" << choice() << ":s" << from << "o" << i << " -> n" |
+ << choice()->alternatives()->at(i).node() << ";\n"; |
} |
} |
} |
private: |
- StringStream* stream() { return stream_; } |
ChoiceNode* choice() { return choice_; } |
- StringStream* stream_; |
+ OStream& os_; |
ChoiceNode* choice_; |
}; |
class TableEntryHeaderPrinter { |
public: |
- explicit TableEntryHeaderPrinter(StringStream* stream) |
- : first_(true), stream_(stream) { } |
+ explicit TableEntryHeaderPrinter(OStream& os) // NOLINT |
+ : first_(true), |
+ os_(os) {} |
void Call(uc16 from, DispatchTable::Entry entry) { |
if (first_) { |
first_ = false; |
} else { |
- stream()->Add("|"); |
+ os_ << "|"; |
} |
- stream()->Add("{\\%k-\\%k|{", from, entry.to()); |
+ os_ << "{\\" << AsUC16(from) << "-\\" << AsUC16(entry.to()) << "|{"; |
OutSet* out_set = entry.out_set(); |
int priority = 0; |
for (unsigned i = 0; i < OutSet::kFirstLimit; i++) { |
if (out_set->Get(i)) { |
- if (priority > 0) stream()->Add("|"); |
- stream()->Add("<s%io%i> %i", from, i, priority); |
+ if (priority > 0) os_ << "|"; |
+ os_ << "<s" << from << "o" << i << "> " << priority; |
priority++; |
} |
} |
- stream()->Add("}}"); |
+ os_ << "}}"; |
} |
private: |
bool first_; |
- StringStream* stream() { return stream_; } |
- StringStream* stream_; |
+ OStream& os_; |
}; |
class AttributePrinter { |
public: |
- explicit AttributePrinter(DotPrinter* out) |
- : out_(out), first_(true) { } |
+ explicit AttributePrinter(OStream& os) // NOLINT |
+ : os_(os), |
+ first_(true) {} |
void PrintSeparator() { |
if (first_) { |
first_ = false; |
} else { |
- out_->stream()->Add("|"); |
+ os_ << "|"; |
} |
} |
void PrintBit(const char* name, bool value) { |
if (!value) return; |
PrintSeparator(); |
- out_->stream()->Add("{%s}", name); |
+ os_ << "{" << name << "}"; |
} |
void PrintPositive(const char* name, int value) { |
if (value < 0) return; |
PrintSeparator(); |
- out_->stream()->Add("{%s|%x}", name, value); |
+ os_ << "{" << name << "|" << value << "}"; |
} |
+ |
private: |
- DotPrinter* out_; |
+ OStream& os_; |
bool first_; |
}; |
void DotPrinter::PrintAttributes(RegExpNode* that) { |
- stream()->Add(" a%p [shape=Mrecord, color=grey, fontcolor=grey, " |
- "margin=0.1, fontsize=10, label=\"{", |
- that); |
- AttributePrinter printer(this); |
+ os_ << " a" << that << " [shape=Mrecord, color=grey, fontcolor=grey, " |
+ << "margin=0.1, fontsize=10, label=\"{"; |
+ AttributePrinter printer(os_); |
NodeInfo* info = that->info(); |
printer.PrintBit("NI", info->follows_newline_interest); |
printer.PrintBit("WI", info->follows_word_interest); |
@@ -4470,27 +4465,27 @@ void DotPrinter::PrintAttributes(RegExpNode* that) { |
Label* label = that->label(); |
if (label->is_bound()) |
printer.PrintPositive("@", label->pos()); |
- stream()->Add("}\"];\n"); |
- stream()->Add(" a%p -> n%p [style=dashed, color=grey, " |
- "arrowhead=none];\n", that, that); |
+ os_ << "}\"];\n" |
+ << " a" << that << " -> n" << that |
+ << " [style=dashed, color=grey, arrowhead=none];\n"; |
} |
static const bool kPrintDispatchTable = false; |
void DotPrinter::VisitChoice(ChoiceNode* that) { |
if (kPrintDispatchTable) { |
- stream()->Add(" n%p [shape=Mrecord, label=\"", that); |
- TableEntryHeaderPrinter header_printer(stream()); |
+ os_ << " n" << that << " [shape=Mrecord, label=\""; |
+ TableEntryHeaderPrinter header_printer(os_); |
that->GetTable(ignore_case_)->ForEach(&header_printer); |
- stream()->Add("\"]\n", that); |
+ os_ << "\"]\n"; |
PrintAttributes(that); |
- TableEntryBodyPrinter body_printer(stream(), that); |
+ TableEntryBodyPrinter body_printer(os_, that); |
that->GetTable(ignore_case_)->ForEach(&body_printer); |
} else { |
- stream()->Add(" n%p [shape=Mrecord, label=\"?\"];\n", that); |
+ os_ << " n" << that << " [shape=Mrecord, label=\"?\"];\n"; |
for (int i = 0; i < that->alternatives()->length(); i++) { |
GuardedAlternative alt = that->alternatives()->at(i); |
- stream()->Add(" n%p -> n%p;\n", that, alt.node()); |
+ os_ << " n" << that << " -> n" << alt.node(); |
} |
} |
for (int i = 0; i < that->alternatives()->length(); i++) { |
@@ -4502,138 +4497,136 @@ void DotPrinter::VisitChoice(ChoiceNode* that) { |
void DotPrinter::VisitText(TextNode* that) { |
Zone* zone = that->zone(); |
- stream()->Add(" n%p [label=\"", that); |
+ os_ << " n" << that << " [label=\""; |
for (int i = 0; i < that->elements()->length(); i++) { |
- if (i > 0) stream()->Add(" "); |
+ if (i > 0) os_ << " "; |
TextElement elm = that->elements()->at(i); |
switch (elm.text_type()) { |
case TextElement::ATOM: { |
- stream()->Add("'%w'", elm.atom()->data()); |
+ Vector<const uc16> data = elm.atom()->data(); |
+ for (int i = 0; i < data.length(); i++) { |
+ os_ << static_cast<char>(data[i]); |
+ } |
break; |
} |
case TextElement::CHAR_CLASS: { |
RegExpCharacterClass* node = elm.char_class(); |
- stream()->Add("["); |
- if (node->is_negated()) |
- stream()->Add("^"); |
+ os_ << "["; |
+ if (node->is_negated()) os_ << "^"; |
for (int j = 0; j < node->ranges(zone)->length(); j++) { |
CharacterRange range = node->ranges(zone)->at(j); |
- stream()->Add("%k-%k", range.from(), range.to()); |
+ os_ << AsUC16(range.from()) << "-" << AsUC16(range.to()); |
} |
- stream()->Add("]"); |
+ os_ << "]"; |
break; |
} |
default: |
UNREACHABLE(); |
} |
} |
- stream()->Add("\", shape=box, peripheries=2];\n"); |
+ os_ << "\", shape=box, peripheries=2];\n"; |
PrintAttributes(that); |
- stream()->Add(" n%p -> n%p;\n", that, that->on_success()); |
+ os_ << " n" << that << " -> n" << that->on_success() << ";\n"; |
Visit(that->on_success()); |
} |
void DotPrinter::VisitBackReference(BackReferenceNode* that) { |
- stream()->Add(" n%p [label=\"$%i..$%i\", shape=doubleoctagon];\n", |
- that, |
- that->start_register(), |
- that->end_register()); |
+ os_ << " n" << that << " [label=\"$" << that->start_register() << "..$" |
+ << that->end_register() << "\", shape=doubleoctagon];\n"; |
PrintAttributes(that); |
- stream()->Add(" n%p -> n%p;\n", that, that->on_success()); |
+ os_ << " n" << that << " -> n" << that->on_success() << ";\n"; |
Visit(that->on_success()); |
} |
void DotPrinter::VisitEnd(EndNode* that) { |
- stream()->Add(" n%p [style=bold, shape=point];\n", that); |
+ os_ << " n" << that << " [style=bold, shape=point];\n"; |
PrintAttributes(that); |
} |
void DotPrinter::VisitAssertion(AssertionNode* that) { |
- stream()->Add(" n%p [", that); |
+ os_ << " n" << that << " ["; |
switch (that->assertion_type()) { |
case AssertionNode::AT_END: |
- stream()->Add("label=\"$\", shape=septagon"); |
+ os_ << "label=\"$\", shape=septagon"; |
break; |
case AssertionNode::AT_START: |
- stream()->Add("label=\"^\", shape=septagon"); |
+ os_ << "label=\"^\", shape=septagon"; |
break; |
case AssertionNode::AT_BOUNDARY: |
- stream()->Add("label=\"\\b\", shape=septagon"); |
+ os_ << "label=\"\\b\", shape=septagon"; |
break; |
case AssertionNode::AT_NON_BOUNDARY: |
- stream()->Add("label=\"\\B\", shape=septagon"); |
+ os_ << "label=\"\\B\", shape=septagon"; |
break; |
case AssertionNode::AFTER_NEWLINE: |
- stream()->Add("label=\"(?<=\\n)\", shape=septagon"); |
+ os_ << "label=\"(?<=\\n)\", shape=septagon"; |
break; |
} |
- stream()->Add("];\n"); |
+ os_ << "];\n"; |
PrintAttributes(that); |
RegExpNode* successor = that->on_success(); |
- stream()->Add(" n%p -> n%p;\n", that, successor); |
+ os_ << " n" << that << " -> n" << successor << ";\n"; |
Visit(successor); |
} |
void DotPrinter::VisitAction(ActionNode* that) { |
- stream()->Add(" n%p [", that); |
+ os_ << " n" << that << " ["; |
switch (that->action_type_) { |
case ActionNode::SET_REGISTER: |
- stream()->Add("label=\"$%i:=%i\", shape=octagon", |
- that->data_.u_store_register.reg, |
- that->data_.u_store_register.value); |
+ os_ << "label=\"$" << that->data_.u_store_register.reg |
+ << ":=" << that->data_.u_store_register.value << "\", shape=octagon"; |
break; |
case ActionNode::INCREMENT_REGISTER: |
- stream()->Add("label=\"$%i++\", shape=octagon", |
- that->data_.u_increment_register.reg); |
+ os_ << "label=\"$" << that->data_.u_increment_register.reg |
+ << "++\", shape=octagon"; |
break; |
case ActionNode::STORE_POSITION: |
- stream()->Add("label=\"$%i:=$pos\", shape=octagon", |
- that->data_.u_position_register.reg); |
+ os_ << "label=\"$" << that->data_.u_position_register.reg |
+ << ":=$pos\", shape=octagon"; |
break; |
case ActionNode::BEGIN_SUBMATCH: |
- stream()->Add("label=\"$%i:=$pos,begin\", shape=septagon", |
- that->data_.u_submatch.current_position_register); |
+ os_ << "label=\"$" << that->data_.u_submatch.current_position_register |
+ << ":=$pos,begin\", shape=septagon"; |
break; |
case ActionNode::POSITIVE_SUBMATCH_SUCCESS: |
- stream()->Add("label=\"escape\", shape=septagon"); |
+ os_ << "label=\"escape\", shape=septagon"; |
break; |
case ActionNode::EMPTY_MATCH_CHECK: |
- stream()->Add("label=\"$%i=$pos?,$%i<%i?\", shape=septagon", |
- that->data_.u_empty_match_check.start_register, |
- that->data_.u_empty_match_check.repetition_register, |
- that->data_.u_empty_match_check.repetition_limit); |
+ os_ << "label=\"$" << that->data_.u_empty_match_check.start_register |
+ << "=$pos?,$" << that->data_.u_empty_match_check.repetition_register |
+ << "<" << that->data_.u_empty_match_check.repetition_limit |
+ << "?\", shape=septagon"; |
break; |
case ActionNode::CLEAR_CAPTURES: { |
- stream()->Add("label=\"clear $%i to $%i\", shape=septagon", |
- that->data_.u_clear_captures.range_from, |
- that->data_.u_clear_captures.range_to); |
+ os_ << "label=\"clear $" << that->data_.u_clear_captures.range_from |
+ << " to $" << that->data_.u_clear_captures.range_to |
+ << "\", shape=septagon"; |
break; |
} |
} |
- stream()->Add("];\n"); |
+ os_ << "];\n"; |
PrintAttributes(that); |
RegExpNode* successor = that->on_success(); |
- stream()->Add(" n%p -> n%p;\n", that, successor); |
+ os_ << " n" << that << " -> n" << successor << ";\n"; |
Visit(successor); |
} |
class DispatchTableDumper { |
public: |
- explicit DispatchTableDumper(StringStream* stream) : stream_(stream) { } |
+ explicit DispatchTableDumper(OStream& os) : os_(os) {} |
void Call(uc16 key, DispatchTable::Entry entry); |
- StringStream* stream() { return stream_; } |
private: |
- StringStream* stream_; |
+ OStream& os_; |
}; |
void DispatchTableDumper::Call(uc16 key, DispatchTable::Entry entry) { |
- stream()->Add("[%k-%k]: {", key, entry.to()); |
+ os_ << "[" << AsUC16(key) << "-" << AsUC16(entry.to()) << "]: {"; |
OutSet* set = entry.out_set(); |
bool first = true; |
for (unsigned i = 0; i < OutSet::kFirstLimit; i++) { |
@@ -4641,28 +4634,27 @@ void DispatchTableDumper::Call(uc16 key, DispatchTable::Entry entry) { |
if (first) { |
first = false; |
} else { |
- stream()->Add(", "); |
+ os_ << ", "; |
} |
- stream()->Add("%i", i); |
+ os_ << i; |
} |
} |
- stream()->Add("}\n"); |
+ os_ << "}\n"; |
} |
void DispatchTable::Dump() { |
- HeapStringAllocator alloc; |
- StringStream stream(&alloc); |
- DispatchTableDumper dumper(&stream); |
+ OFStream os(stderr); |
+ DispatchTableDumper dumper(os); |
tree()->ForEach(&dumper); |
- base::OS::PrintError("%s", stream.ToCString().get()); |
} |
void RegExpEngine::DotPrint(const char* label, |
RegExpNode* node, |
bool ignore_case) { |
- DotPrinter printer(ignore_case); |
+ OFStream os(stdout); |
+ DotPrinter printer(os, ignore_case); |
printer.PrintNode(label, node); |
} |