OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/ast.h" | 7 #include "src/ast.h" |
8 #include "src/base/platform/platform.h" | 8 #include "src/base/platform/platform.h" |
9 #include "src/compilation-cache.h" | 9 #include "src/compilation-cache.h" |
10 #include "src/compiler.h" | 10 #include "src/compiler.h" |
11 #include "src/execution.h" | 11 #include "src/execution.h" |
12 #include "src/factory.h" | 12 #include "src/factory.h" |
13 #include "src/jsregexp-inl.h" | 13 #include "src/jsregexp-inl.h" |
14 #include "src/jsregexp.h" | 14 #include "src/jsregexp.h" |
| 15 #include "src/ostreams.h" |
15 #include "src/parser.h" | 16 #include "src/parser.h" |
16 #include "src/regexp-macro-assembler.h" | 17 #include "src/regexp-macro-assembler.h" |
17 #include "src/regexp-macro-assembler-irregexp.h" | 18 #include "src/regexp-macro-assembler-irregexp.h" |
18 #include "src/regexp-macro-assembler-tracer.h" | 19 #include "src/regexp-macro-assembler-tracer.h" |
19 #include "src/regexp-stack.h" | 20 #include "src/regexp-stack.h" |
20 #include "src/runtime.h" | 21 #include "src/runtime.h" |
21 #include "src/string-search.h" | 22 #include "src/string-search.h" |
22 #include "src/string-stream.h" | |
23 | 23 |
24 #ifndef V8_INTERPRETED_REGEXP | 24 #ifndef V8_INTERPRETED_REGEXP |
25 #if V8_TARGET_ARCH_IA32 | 25 #if V8_TARGET_ARCH_IA32 |
26 #include "src/ia32/regexp-macro-assembler-ia32.h" // NOLINT | 26 #include "src/ia32/regexp-macro-assembler-ia32.h" // NOLINT |
27 #elif V8_TARGET_ARCH_X64 | 27 #elif V8_TARGET_ARCH_X64 |
28 #include "src/x64/regexp-macro-assembler-x64.h" // NOLINT | 28 #include "src/x64/regexp-macro-assembler-x64.h" // NOLINT |
29 #elif V8_TARGET_ARCH_ARM64 | 29 #elif V8_TARGET_ARCH_ARM64 |
30 #include "src/arm64/regexp-macro-assembler-arm64.h" // NOLINT | 30 #include "src/arm64/regexp-macro-assembler-arm64.h" // NOLINT |
31 #elif V8_TARGET_ARCH_ARM | 31 #elif V8_TARGET_ARCH_ARM |
32 #include "src/arm/regexp-macro-assembler-arm.h" // NOLINT | 32 #include "src/arm/regexp-macro-assembler-arm.h" // NOLINT |
(...skipping 1093 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1126 work_list.RemoveLast()->Emit(this, &new_trace); | 1126 work_list.RemoveLast()->Emit(this, &new_trace); |
1127 } | 1127 } |
1128 if (reg_exp_too_big_) return IrregexpRegExpTooBig(zone_->isolate()); | 1128 if (reg_exp_too_big_) return IrregexpRegExpTooBig(zone_->isolate()); |
1129 | 1129 |
1130 Handle<HeapObject> code = macro_assembler_->GetCode(pattern); | 1130 Handle<HeapObject> code = macro_assembler_->GetCode(pattern); |
1131 heap->IncreaseTotalRegexpCodeGenerated(code->Size()); | 1131 heap->IncreaseTotalRegexpCodeGenerated(code->Size()); |
1132 work_list_ = NULL; | 1132 work_list_ = NULL; |
1133 #ifdef DEBUG | 1133 #ifdef DEBUG |
1134 if (FLAG_print_code) { | 1134 if (FLAG_print_code) { |
1135 CodeTracer::Scope trace_scope(heap->isolate()->GetCodeTracer()); | 1135 CodeTracer::Scope trace_scope(heap->isolate()->GetCodeTracer()); |
1136 Handle<Code>::cast(code)->Disassemble(pattern->ToCString().get(), | 1136 OFStream os(trace_scope.file()); |
1137 trace_scope.file()); | 1137 Handle<Code>::cast(code)->Disassemble(pattern->ToCString().get(), os); |
1138 } | 1138 } |
1139 if (FLAG_trace_regexp_assembler) { | 1139 if (FLAG_trace_regexp_assembler) { |
1140 delete macro_assembler_; | 1140 delete macro_assembler_; |
1141 } | 1141 } |
1142 #endif | 1142 #endif |
1143 return RegExpEngine::CompilationResult(*code, next_register_); | 1143 return RegExpEngine::CompilationResult(*code, next_register_); |
1144 } | 1144 } |
1145 | 1145 |
1146 | 1146 |
1147 bool Trace::DeferredAction::Mentions(int that) { | 1147 bool Trace::DeferredAction::Mentions(int that) { |
(...skipping 3168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4316 | 4316 |
4317 // ------------------------------------------------------------------- | 4317 // ------------------------------------------------------------------- |
4318 // Dot/dotty output | 4318 // Dot/dotty output |
4319 | 4319 |
4320 | 4320 |
4321 #ifdef DEBUG | 4321 #ifdef DEBUG |
4322 | 4322 |
4323 | 4323 |
4324 class DotPrinter: public NodeVisitor { | 4324 class DotPrinter: public NodeVisitor { |
4325 public: | 4325 public: |
4326 explicit DotPrinter(bool ignore_case) | 4326 DotPrinter(OStream& os, bool ignore_case) // NOLINT |
4327 : ignore_case_(ignore_case), | 4327 : os_(os), |
4328 stream_(&alloc_) { } | 4328 ignore_case_(ignore_case) {} |
4329 void PrintNode(const char* label, RegExpNode* node); | 4329 void PrintNode(const char* label, RegExpNode* node); |
4330 void Visit(RegExpNode* node); | 4330 void Visit(RegExpNode* node); |
4331 void PrintAttributes(RegExpNode* from); | 4331 void PrintAttributes(RegExpNode* from); |
4332 StringStream* stream() { return &stream_; } | |
4333 void PrintOnFailure(RegExpNode* from, RegExpNode* to); | 4332 void PrintOnFailure(RegExpNode* from, RegExpNode* to); |
4334 #define DECLARE_VISIT(Type) \ | 4333 #define DECLARE_VISIT(Type) \ |
4335 virtual void Visit##Type(Type##Node* that); | 4334 virtual void Visit##Type(Type##Node* that); |
4336 FOR_EACH_NODE_TYPE(DECLARE_VISIT) | 4335 FOR_EACH_NODE_TYPE(DECLARE_VISIT) |
4337 #undef DECLARE_VISIT | 4336 #undef DECLARE_VISIT |
4338 private: | 4337 private: |
| 4338 OStream& os_; |
4339 bool ignore_case_; | 4339 bool ignore_case_; |
4340 HeapStringAllocator alloc_; | |
4341 StringStream stream_; | |
4342 }; | 4340 }; |
4343 | 4341 |
4344 | 4342 |
4345 void DotPrinter::PrintNode(const char* label, RegExpNode* node) { | 4343 void DotPrinter::PrintNode(const char* label, RegExpNode* node) { |
4346 stream()->Add("digraph G {\n graph [label=\""); | 4344 os_ << "digraph G {\n graph [label=\""; |
4347 for (int i = 0; label[i]; i++) { | 4345 for (int i = 0; label[i]; i++) { |
4348 switch (label[i]) { | 4346 switch (label[i]) { |
4349 case '\\': | 4347 case '\\': |
4350 stream()->Add("\\\\"); | 4348 os_ << "\\\\"; |
4351 break; | 4349 break; |
4352 case '"': | 4350 case '"': |
4353 stream()->Add("\""); | 4351 os_ << "\""; |
4354 break; | 4352 break; |
4355 default: | 4353 default: |
4356 stream()->Put(label[i]); | 4354 os_ << label[i]; |
4357 break; | 4355 break; |
4358 } | 4356 } |
4359 } | 4357 } |
4360 stream()->Add("\"];\n"); | 4358 os_ << "\"];\n"; |
4361 Visit(node); | 4359 Visit(node); |
4362 stream()->Add("}\n"); | 4360 os_ << "}" << endl; |
4363 printf("%s", stream()->ToCString().get()); | |
4364 } | 4361 } |
4365 | 4362 |
4366 | 4363 |
4367 void DotPrinter::Visit(RegExpNode* node) { | 4364 void DotPrinter::Visit(RegExpNode* node) { |
4368 if (node->info()->visited) return; | 4365 if (node->info()->visited) return; |
4369 node->info()->visited = true; | 4366 node->info()->visited = true; |
4370 node->Accept(this); | 4367 node->Accept(this); |
4371 } | 4368 } |
4372 | 4369 |
4373 | 4370 |
4374 void DotPrinter::PrintOnFailure(RegExpNode* from, RegExpNode* on_failure) { | 4371 void DotPrinter::PrintOnFailure(RegExpNode* from, RegExpNode* on_failure) { |
4375 stream()->Add(" n%p -> n%p [style=dotted];\n", from, on_failure); | 4372 os_ << " n" << from << " -> n" << on_failure << " [style=dotted];\n"; |
4376 Visit(on_failure); | 4373 Visit(on_failure); |
4377 } | 4374 } |
4378 | 4375 |
4379 | 4376 |
4380 class TableEntryBodyPrinter { | 4377 class TableEntryBodyPrinter { |
4381 public: | 4378 public: |
4382 TableEntryBodyPrinter(StringStream* stream, ChoiceNode* choice) | 4379 TableEntryBodyPrinter(OStream& os, ChoiceNode* choice) // NOLINT |
4383 : stream_(stream), choice_(choice) { } | 4380 : os_(os), |
| 4381 choice_(choice) {} |
4384 void Call(uc16 from, DispatchTable::Entry entry) { | 4382 void Call(uc16 from, DispatchTable::Entry entry) { |
4385 OutSet* out_set = entry.out_set(); | 4383 OutSet* out_set = entry.out_set(); |
4386 for (unsigned i = 0; i < OutSet::kFirstLimit; i++) { | 4384 for (unsigned i = 0; i < OutSet::kFirstLimit; i++) { |
4387 if (out_set->Get(i)) { | 4385 if (out_set->Get(i)) { |
4388 stream()->Add(" n%p:s%io%i -> n%p;\n", | 4386 os_ << " n" << choice() << ":s" << from << "o" << i << " -> n" |
4389 choice(), | 4387 << choice()->alternatives()->at(i).node() << ";\n"; |
4390 from, | |
4391 i, | |
4392 choice()->alternatives()->at(i).node()); | |
4393 } | 4388 } |
4394 } | 4389 } |
4395 } | 4390 } |
4396 private: | 4391 private: |
4397 StringStream* stream() { return stream_; } | |
4398 ChoiceNode* choice() { return choice_; } | 4392 ChoiceNode* choice() { return choice_; } |
4399 StringStream* stream_; | 4393 OStream& os_; |
4400 ChoiceNode* choice_; | 4394 ChoiceNode* choice_; |
4401 }; | 4395 }; |
4402 | 4396 |
4403 | 4397 |
4404 class TableEntryHeaderPrinter { | 4398 class TableEntryHeaderPrinter { |
4405 public: | 4399 public: |
4406 explicit TableEntryHeaderPrinter(StringStream* stream) | 4400 explicit TableEntryHeaderPrinter(OStream& os) // NOLINT |
4407 : first_(true), stream_(stream) { } | 4401 : first_(true), |
| 4402 os_(os) {} |
4408 void Call(uc16 from, DispatchTable::Entry entry) { | 4403 void Call(uc16 from, DispatchTable::Entry entry) { |
4409 if (first_) { | 4404 if (first_) { |
4410 first_ = false; | 4405 first_ = false; |
4411 } else { | 4406 } else { |
4412 stream()->Add("|"); | 4407 os_ << "|"; |
4413 } | 4408 } |
4414 stream()->Add("{\\%k-\\%k|{", from, entry.to()); | 4409 os_ << "{\\" << AsUC16(from) << "-\\" << AsUC16(entry.to()) << "|{"; |
4415 OutSet* out_set = entry.out_set(); | 4410 OutSet* out_set = entry.out_set(); |
4416 int priority = 0; | 4411 int priority = 0; |
4417 for (unsigned i = 0; i < OutSet::kFirstLimit; i++) { | 4412 for (unsigned i = 0; i < OutSet::kFirstLimit; i++) { |
4418 if (out_set->Get(i)) { | 4413 if (out_set->Get(i)) { |
4419 if (priority > 0) stream()->Add("|"); | 4414 if (priority > 0) os_ << "|"; |
4420 stream()->Add("<s%io%i> %i", from, i, priority); | 4415 os_ << "<s" << from << "o" << i << "> " << priority; |
4421 priority++; | 4416 priority++; |
4422 } | 4417 } |
4423 } | 4418 } |
4424 stream()->Add("}}"); | 4419 os_ << "}}"; |
4425 } | 4420 } |
4426 | 4421 |
4427 private: | 4422 private: |
4428 bool first_; | 4423 bool first_; |
4429 StringStream* stream() { return stream_; } | 4424 OStream& os_; |
4430 StringStream* stream_; | |
4431 }; | 4425 }; |
4432 | 4426 |
4433 | 4427 |
4434 class AttributePrinter { | 4428 class AttributePrinter { |
4435 public: | 4429 public: |
4436 explicit AttributePrinter(DotPrinter* out) | 4430 explicit AttributePrinter(OStream& os) // NOLINT |
4437 : out_(out), first_(true) { } | 4431 : os_(os), |
| 4432 first_(true) {} |
4438 void PrintSeparator() { | 4433 void PrintSeparator() { |
4439 if (first_) { | 4434 if (first_) { |
4440 first_ = false; | 4435 first_ = false; |
4441 } else { | 4436 } else { |
4442 out_->stream()->Add("|"); | 4437 os_ << "|"; |
4443 } | 4438 } |
4444 } | 4439 } |
4445 void PrintBit(const char* name, bool value) { | 4440 void PrintBit(const char* name, bool value) { |
4446 if (!value) return; | 4441 if (!value) return; |
4447 PrintSeparator(); | 4442 PrintSeparator(); |
4448 out_->stream()->Add("{%s}", name); | 4443 os_ << "{" << name << "}"; |
4449 } | 4444 } |
4450 void PrintPositive(const char* name, int value) { | 4445 void PrintPositive(const char* name, int value) { |
4451 if (value < 0) return; | 4446 if (value < 0) return; |
4452 PrintSeparator(); | 4447 PrintSeparator(); |
4453 out_->stream()->Add("{%s|%x}", name, value); | 4448 os_ << "{" << name << "|" << value << "}"; |
4454 } | 4449 } |
| 4450 |
4455 private: | 4451 private: |
4456 DotPrinter* out_; | 4452 OStream& os_; |
4457 bool first_; | 4453 bool first_; |
4458 }; | 4454 }; |
4459 | 4455 |
4460 | 4456 |
4461 void DotPrinter::PrintAttributes(RegExpNode* that) { | 4457 void DotPrinter::PrintAttributes(RegExpNode* that) { |
4462 stream()->Add(" a%p [shape=Mrecord, color=grey, fontcolor=grey, " | 4458 os_ << " a" << that << " [shape=Mrecord, color=grey, fontcolor=grey, " |
4463 "margin=0.1, fontsize=10, label=\"{", | 4459 << "margin=0.1, fontsize=10, label=\"{"; |
4464 that); | 4460 AttributePrinter printer(os_); |
4465 AttributePrinter printer(this); | |
4466 NodeInfo* info = that->info(); | 4461 NodeInfo* info = that->info(); |
4467 printer.PrintBit("NI", info->follows_newline_interest); | 4462 printer.PrintBit("NI", info->follows_newline_interest); |
4468 printer.PrintBit("WI", info->follows_word_interest); | 4463 printer.PrintBit("WI", info->follows_word_interest); |
4469 printer.PrintBit("SI", info->follows_start_interest); | 4464 printer.PrintBit("SI", info->follows_start_interest); |
4470 Label* label = that->label(); | 4465 Label* label = that->label(); |
4471 if (label->is_bound()) | 4466 if (label->is_bound()) |
4472 printer.PrintPositive("@", label->pos()); | 4467 printer.PrintPositive("@", label->pos()); |
4473 stream()->Add("}\"];\n"); | 4468 os_ << "}\"];\n" |
4474 stream()->Add(" a%p -> n%p [style=dashed, color=grey, " | 4469 << " a" << that << " -> n" << that |
4475 "arrowhead=none];\n", that, that); | 4470 << " [style=dashed, color=grey, arrowhead=none];\n"; |
4476 } | 4471 } |
4477 | 4472 |
4478 | 4473 |
4479 static const bool kPrintDispatchTable = false; | 4474 static const bool kPrintDispatchTable = false; |
4480 void DotPrinter::VisitChoice(ChoiceNode* that) { | 4475 void DotPrinter::VisitChoice(ChoiceNode* that) { |
4481 if (kPrintDispatchTable) { | 4476 if (kPrintDispatchTable) { |
4482 stream()->Add(" n%p [shape=Mrecord, label=\"", that); | 4477 os_ << " n" << that << " [shape=Mrecord, label=\""; |
4483 TableEntryHeaderPrinter header_printer(stream()); | 4478 TableEntryHeaderPrinter header_printer(os_); |
4484 that->GetTable(ignore_case_)->ForEach(&header_printer); | 4479 that->GetTable(ignore_case_)->ForEach(&header_printer); |
4485 stream()->Add("\"]\n", that); | 4480 os_ << "\"]\n"; |
4486 PrintAttributes(that); | 4481 PrintAttributes(that); |
4487 TableEntryBodyPrinter body_printer(stream(), that); | 4482 TableEntryBodyPrinter body_printer(os_, that); |
4488 that->GetTable(ignore_case_)->ForEach(&body_printer); | 4483 that->GetTable(ignore_case_)->ForEach(&body_printer); |
4489 } else { | 4484 } else { |
4490 stream()->Add(" n%p [shape=Mrecord, label=\"?\"];\n", that); | 4485 os_ << " n" << that << " [shape=Mrecord, label=\"?\"];\n"; |
4491 for (int i = 0; i < that->alternatives()->length(); i++) { | 4486 for (int i = 0; i < that->alternatives()->length(); i++) { |
4492 GuardedAlternative alt = that->alternatives()->at(i); | 4487 GuardedAlternative alt = that->alternatives()->at(i); |
4493 stream()->Add(" n%p -> n%p;\n", that, alt.node()); | 4488 os_ << " n" << that << " -> n" << alt.node(); |
4494 } | 4489 } |
4495 } | 4490 } |
4496 for (int i = 0; i < that->alternatives()->length(); i++) { | 4491 for (int i = 0; i < that->alternatives()->length(); i++) { |
4497 GuardedAlternative alt = that->alternatives()->at(i); | 4492 GuardedAlternative alt = that->alternatives()->at(i); |
4498 alt.node()->Accept(this); | 4493 alt.node()->Accept(this); |
4499 } | 4494 } |
4500 } | 4495 } |
4501 | 4496 |
4502 | 4497 |
4503 void DotPrinter::VisitText(TextNode* that) { | 4498 void DotPrinter::VisitText(TextNode* that) { |
4504 Zone* zone = that->zone(); | 4499 Zone* zone = that->zone(); |
4505 stream()->Add(" n%p [label=\"", that); | 4500 os_ << " n" << that << " [label=\""; |
4506 for (int i = 0; i < that->elements()->length(); i++) { | 4501 for (int i = 0; i < that->elements()->length(); i++) { |
4507 if (i > 0) stream()->Add(" "); | 4502 if (i > 0) os_ << " "; |
4508 TextElement elm = that->elements()->at(i); | 4503 TextElement elm = that->elements()->at(i); |
4509 switch (elm.text_type()) { | 4504 switch (elm.text_type()) { |
4510 case TextElement::ATOM: { | 4505 case TextElement::ATOM: { |
4511 stream()->Add("'%w'", elm.atom()->data()); | 4506 Vector<const uc16> data = elm.atom()->data(); |
| 4507 for (int i = 0; i < data.length(); i++) { |
| 4508 os_ << static_cast<char>(data[i]); |
| 4509 } |
4512 break; | 4510 break; |
4513 } | 4511 } |
4514 case TextElement::CHAR_CLASS: { | 4512 case TextElement::CHAR_CLASS: { |
4515 RegExpCharacterClass* node = elm.char_class(); | 4513 RegExpCharacterClass* node = elm.char_class(); |
4516 stream()->Add("["); | 4514 os_ << "["; |
4517 if (node->is_negated()) | 4515 if (node->is_negated()) os_ << "^"; |
4518 stream()->Add("^"); | |
4519 for (int j = 0; j < node->ranges(zone)->length(); j++) { | 4516 for (int j = 0; j < node->ranges(zone)->length(); j++) { |
4520 CharacterRange range = node->ranges(zone)->at(j); | 4517 CharacterRange range = node->ranges(zone)->at(j); |
4521 stream()->Add("%k-%k", range.from(), range.to()); | 4518 os_ << AsUC16(range.from()) << "-" << AsUC16(range.to()); |
4522 } | 4519 } |
4523 stream()->Add("]"); | 4520 os_ << "]"; |
4524 break; | 4521 break; |
4525 } | 4522 } |
4526 default: | 4523 default: |
4527 UNREACHABLE(); | 4524 UNREACHABLE(); |
4528 } | 4525 } |
4529 } | 4526 } |
4530 stream()->Add("\", shape=box, peripheries=2];\n"); | 4527 os_ << "\", shape=box, peripheries=2];\n"; |
4531 PrintAttributes(that); | 4528 PrintAttributes(that); |
4532 stream()->Add(" n%p -> n%p;\n", that, that->on_success()); | 4529 os_ << " n" << that << " -> n" << that->on_success() << ";\n"; |
4533 Visit(that->on_success()); | 4530 Visit(that->on_success()); |
4534 } | 4531 } |
4535 | 4532 |
4536 | 4533 |
4537 void DotPrinter::VisitBackReference(BackReferenceNode* that) { | 4534 void DotPrinter::VisitBackReference(BackReferenceNode* that) { |
4538 stream()->Add(" n%p [label=\"$%i..$%i\", shape=doubleoctagon];\n", | 4535 os_ << " n" << that << " [label=\"$" << that->start_register() << "..$" |
4539 that, | 4536 << that->end_register() << "\", shape=doubleoctagon];\n"; |
4540 that->start_register(), | |
4541 that->end_register()); | |
4542 PrintAttributes(that); | 4537 PrintAttributes(that); |
4543 stream()->Add(" n%p -> n%p;\n", that, that->on_success()); | 4538 os_ << " n" << that << " -> n" << that->on_success() << ";\n"; |
4544 Visit(that->on_success()); | 4539 Visit(that->on_success()); |
4545 } | 4540 } |
4546 | 4541 |
4547 | 4542 |
4548 void DotPrinter::VisitEnd(EndNode* that) { | 4543 void DotPrinter::VisitEnd(EndNode* that) { |
4549 stream()->Add(" n%p [style=bold, shape=point];\n", that); | 4544 os_ << " n" << that << " [style=bold, shape=point];\n"; |
4550 PrintAttributes(that); | 4545 PrintAttributes(that); |
4551 } | 4546 } |
4552 | 4547 |
4553 | 4548 |
4554 void DotPrinter::VisitAssertion(AssertionNode* that) { | 4549 void DotPrinter::VisitAssertion(AssertionNode* that) { |
4555 stream()->Add(" n%p [", that); | 4550 os_ << " n" << that << " ["; |
4556 switch (that->assertion_type()) { | 4551 switch (that->assertion_type()) { |
4557 case AssertionNode::AT_END: | 4552 case AssertionNode::AT_END: |
4558 stream()->Add("label=\"$\", shape=septagon"); | 4553 os_ << "label=\"$\", shape=septagon"; |
4559 break; | 4554 break; |
4560 case AssertionNode::AT_START: | 4555 case AssertionNode::AT_START: |
4561 stream()->Add("label=\"^\", shape=septagon"); | 4556 os_ << "label=\"^\", shape=septagon"; |
4562 break; | 4557 break; |
4563 case AssertionNode::AT_BOUNDARY: | 4558 case AssertionNode::AT_BOUNDARY: |
4564 stream()->Add("label=\"\\b\", shape=septagon"); | 4559 os_ << "label=\"\\b\", shape=septagon"; |
4565 break; | 4560 break; |
4566 case AssertionNode::AT_NON_BOUNDARY: | 4561 case AssertionNode::AT_NON_BOUNDARY: |
4567 stream()->Add("label=\"\\B\", shape=septagon"); | 4562 os_ << "label=\"\\B\", shape=septagon"; |
4568 break; | 4563 break; |
4569 case AssertionNode::AFTER_NEWLINE: | 4564 case AssertionNode::AFTER_NEWLINE: |
4570 stream()->Add("label=\"(?<=\\n)\", shape=septagon"); | 4565 os_ << "label=\"(?<=\\n)\", shape=septagon"; |
4571 break; | 4566 break; |
4572 } | 4567 } |
4573 stream()->Add("];\n"); | 4568 os_ << "];\n"; |
4574 PrintAttributes(that); | 4569 PrintAttributes(that); |
4575 RegExpNode* successor = that->on_success(); | 4570 RegExpNode* successor = that->on_success(); |
4576 stream()->Add(" n%p -> n%p;\n", that, successor); | 4571 os_ << " n" << that << " -> n" << successor << ";\n"; |
4577 Visit(successor); | 4572 Visit(successor); |
4578 } | 4573 } |
4579 | 4574 |
4580 | 4575 |
4581 void DotPrinter::VisitAction(ActionNode* that) { | 4576 void DotPrinter::VisitAction(ActionNode* that) { |
4582 stream()->Add(" n%p [", that); | 4577 os_ << " n" << that << " ["; |
4583 switch (that->action_type_) { | 4578 switch (that->action_type_) { |
4584 case ActionNode::SET_REGISTER: | 4579 case ActionNode::SET_REGISTER: |
4585 stream()->Add("label=\"$%i:=%i\", shape=octagon", | 4580 os_ << "label=\"$" << that->data_.u_store_register.reg |
4586 that->data_.u_store_register.reg, | 4581 << ":=" << that->data_.u_store_register.value << "\", shape=octagon"; |
4587 that->data_.u_store_register.value); | |
4588 break; | 4582 break; |
4589 case ActionNode::INCREMENT_REGISTER: | 4583 case ActionNode::INCREMENT_REGISTER: |
4590 stream()->Add("label=\"$%i++\", shape=octagon", | 4584 os_ << "label=\"$" << that->data_.u_increment_register.reg |
4591 that->data_.u_increment_register.reg); | 4585 << "++\", shape=octagon"; |
4592 break; | 4586 break; |
4593 case ActionNode::STORE_POSITION: | 4587 case ActionNode::STORE_POSITION: |
4594 stream()->Add("label=\"$%i:=$pos\", shape=octagon", | 4588 os_ << "label=\"$" << that->data_.u_position_register.reg |
4595 that->data_.u_position_register.reg); | 4589 << ":=$pos\", shape=octagon"; |
4596 break; | 4590 break; |
4597 case ActionNode::BEGIN_SUBMATCH: | 4591 case ActionNode::BEGIN_SUBMATCH: |
4598 stream()->Add("label=\"$%i:=$pos,begin\", shape=septagon", | 4592 os_ << "label=\"$" << that->data_.u_submatch.current_position_register |
4599 that->data_.u_submatch.current_position_register); | 4593 << ":=$pos,begin\", shape=septagon"; |
4600 break; | 4594 break; |
4601 case ActionNode::POSITIVE_SUBMATCH_SUCCESS: | 4595 case ActionNode::POSITIVE_SUBMATCH_SUCCESS: |
4602 stream()->Add("label=\"escape\", shape=septagon"); | 4596 os_ << "label=\"escape\", shape=septagon"; |
4603 break; | 4597 break; |
4604 case ActionNode::EMPTY_MATCH_CHECK: | 4598 case ActionNode::EMPTY_MATCH_CHECK: |
4605 stream()->Add("label=\"$%i=$pos?,$%i<%i?\", shape=septagon", | 4599 os_ << "label=\"$" << that->data_.u_empty_match_check.start_register |
4606 that->data_.u_empty_match_check.start_register, | 4600 << "=$pos?,$" << that->data_.u_empty_match_check.repetition_register |
4607 that->data_.u_empty_match_check.repetition_register, | 4601 << "<" << that->data_.u_empty_match_check.repetition_limit |
4608 that->data_.u_empty_match_check.repetition_limit); | 4602 << "?\", shape=septagon"; |
4609 break; | 4603 break; |
4610 case ActionNode::CLEAR_CAPTURES: { | 4604 case ActionNode::CLEAR_CAPTURES: { |
4611 stream()->Add("label=\"clear $%i to $%i\", shape=septagon", | 4605 os_ << "label=\"clear $" << that->data_.u_clear_captures.range_from |
4612 that->data_.u_clear_captures.range_from, | 4606 << " to $" << that->data_.u_clear_captures.range_to |
4613 that->data_.u_clear_captures.range_to); | 4607 << "\", shape=septagon"; |
4614 break; | 4608 break; |
4615 } | 4609 } |
4616 } | 4610 } |
4617 stream()->Add("];\n"); | 4611 os_ << "];\n"; |
4618 PrintAttributes(that); | 4612 PrintAttributes(that); |
4619 RegExpNode* successor = that->on_success(); | 4613 RegExpNode* successor = that->on_success(); |
4620 stream()->Add(" n%p -> n%p;\n", that, successor); | 4614 os_ << " n" << that << " -> n" << successor << ";\n"; |
4621 Visit(successor); | 4615 Visit(successor); |
4622 } | 4616 } |
4623 | 4617 |
4624 | 4618 |
4625 class DispatchTableDumper { | 4619 class DispatchTableDumper { |
4626 public: | 4620 public: |
4627 explicit DispatchTableDumper(StringStream* stream) : stream_(stream) { } | 4621 explicit DispatchTableDumper(OStream& os) : os_(os) {} |
4628 void Call(uc16 key, DispatchTable::Entry entry); | 4622 void Call(uc16 key, DispatchTable::Entry entry); |
4629 StringStream* stream() { return stream_; } | |
4630 private: | 4623 private: |
4631 StringStream* stream_; | 4624 OStream& os_; |
4632 }; | 4625 }; |
4633 | 4626 |
4634 | 4627 |
4635 void DispatchTableDumper::Call(uc16 key, DispatchTable::Entry entry) { | 4628 void DispatchTableDumper::Call(uc16 key, DispatchTable::Entry entry) { |
4636 stream()->Add("[%k-%k]: {", key, entry.to()); | 4629 os_ << "[" << AsUC16(key) << "-" << AsUC16(entry.to()) << "]: {"; |
4637 OutSet* set = entry.out_set(); | 4630 OutSet* set = entry.out_set(); |
4638 bool first = true; | 4631 bool first = true; |
4639 for (unsigned i = 0; i < OutSet::kFirstLimit; i++) { | 4632 for (unsigned i = 0; i < OutSet::kFirstLimit; i++) { |
4640 if (set->Get(i)) { | 4633 if (set->Get(i)) { |
4641 if (first) { | 4634 if (first) { |
4642 first = false; | 4635 first = false; |
4643 } else { | 4636 } else { |
4644 stream()->Add(", "); | 4637 os_ << ", "; |
4645 } | 4638 } |
4646 stream()->Add("%i", i); | 4639 os_ << i; |
4647 } | 4640 } |
4648 } | 4641 } |
4649 stream()->Add("}\n"); | 4642 os_ << "}\n"; |
4650 } | 4643 } |
4651 | 4644 |
4652 | 4645 |
4653 void DispatchTable::Dump() { | 4646 void DispatchTable::Dump() { |
4654 HeapStringAllocator alloc; | 4647 OFStream os(stderr); |
4655 StringStream stream(&alloc); | 4648 DispatchTableDumper dumper(os); |
4656 DispatchTableDumper dumper(&stream); | |
4657 tree()->ForEach(&dumper); | 4649 tree()->ForEach(&dumper); |
4658 base::OS::PrintError("%s", stream.ToCString().get()); | |
4659 } | 4650 } |
4660 | 4651 |
4661 | 4652 |
4662 void RegExpEngine::DotPrint(const char* label, | 4653 void RegExpEngine::DotPrint(const char* label, |
4663 RegExpNode* node, | 4654 RegExpNode* node, |
4664 bool ignore_case) { | 4655 bool ignore_case) { |
4665 DotPrinter printer(ignore_case); | 4656 OFStream os(stdout); |
| 4657 DotPrinter printer(os, ignore_case); |
4666 printer.PrintNode(label, node); | 4658 printer.PrintNode(label, node); |
4667 } | 4659 } |
4668 | 4660 |
4669 | 4661 |
4670 #endif // DEBUG | 4662 #endif // DEBUG |
4671 | 4663 |
4672 | 4664 |
4673 // ------------------------------------------------------------------- | 4665 // ------------------------------------------------------------------- |
4674 // Tree to graph conversion | 4666 // Tree to graph conversion |
4675 | 4667 |
(...skipping 1431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6107 } | 6099 } |
6108 | 6100 |
6109 return compiler.Assemble(¯o_assembler, | 6101 return compiler.Assemble(¯o_assembler, |
6110 node, | 6102 node, |
6111 data->capture_count, | 6103 data->capture_count, |
6112 pattern); | 6104 pattern); |
6113 } | 6105 } |
6114 | 6106 |
6115 | 6107 |
6116 }} // namespace v8::internal | 6108 }} // namespace v8::internal |
OLD | NEW |