OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 12 matching lines...) Expand all Loading... |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "src/inspector/v8-runtime-agent-impl.h" | 31 #include "src/inspector/v8-runtime-agent-impl.h" |
32 | 32 |
| 33 #include "src/debug/debug-interface.h" |
33 #include "src/inspector/injected-script.h" | 34 #include "src/inspector/injected-script.h" |
34 #include "src/inspector/inspected-context.h" | 35 #include "src/inspector/inspected-context.h" |
35 #include "src/inspector/protocol/Protocol.h" | 36 #include "src/inspector/protocol/Protocol.h" |
36 #include "src/inspector/remote-object-id.h" | 37 #include "src/inspector/remote-object-id.h" |
37 #include "src/inspector/string-util.h" | 38 #include "src/inspector/string-util.h" |
38 #include "src/inspector/v8-console-message.h" | 39 #include "src/inspector/v8-console-message.h" |
39 #include "src/inspector/v8-debugger-agent-impl.h" | 40 #include "src/inspector/v8-debugger-agent-impl.h" |
40 #include "src/inspector/v8-debugger.h" | 41 #include "src/inspector/v8-debugger.h" |
41 #include "src/inspector/v8-inspector-impl.h" | 42 #include "src/inspector/v8-inspector-impl.h" |
42 #include "src/inspector/v8-inspector-session-impl.h" | 43 #include "src/inspector/v8-inspector-session-impl.h" |
43 #include "src/inspector/v8-stack-trace-impl.h" | 44 #include "src/inspector/v8-stack-trace-impl.h" |
44 #include "src/tracing/trace-event.h" | 45 #include "src/tracing/trace-event.h" |
45 | 46 |
46 #include "include/v8-inspector.h" | 47 #include "include/v8-inspector.h" |
47 | 48 |
48 namespace v8_inspector { | 49 namespace v8_inspector { |
49 | 50 |
50 namespace V8RuntimeAgentImplState { | 51 namespace V8RuntimeAgentImplState { |
51 static const char customObjectFormatterEnabled[] = | 52 static const char customObjectFormatterEnabled[] = |
52 "customObjectFormatterEnabled"; | 53 "customObjectFormatterEnabled"; |
53 static const char runtimeEnabled[] = "runtimeEnabled"; | 54 static const char runtimeEnabled[] = "runtimeEnabled"; |
| 55 static const char preciseCoverageStarted[] = "preciseCoverageStarted"; |
54 }; | 56 }; |
55 | 57 |
56 using protocol::Runtime::RemoteObject; | 58 using protocol::Runtime::RemoteObject; |
57 | 59 |
58 namespace { | 60 namespace { |
59 | 61 |
60 template <typename Callback> | 62 template <typename Callback> |
61 class ProtocolPromiseHandler { | 63 class ProtocolPromiseHandler { |
62 public: | 64 public: |
63 static void add(V8InspectorImpl* inspector, v8::Local<v8::Context> context, | 65 static void add(V8InspectorImpl* inspector, v8::Local<v8::Context> context, |
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
638 } | 640 } |
639 ProtocolPromiseHandler<RunScriptCallback>::add( | 641 ProtocolPromiseHandler<RunScriptCallback>::add( |
640 m_inspector, scope.context(), maybeResultValue.ToLocalChecked(), | 642 m_inspector, scope.context(), maybeResultValue.ToLocalChecked(), |
641 "Result of the script execution is not a promise", | 643 "Result of the script execution is not a promise", |
642 m_session->contextGroupId(), | 644 m_session->contextGroupId(), |
643 scope.injectedScript()->context()->contextId(), objectGroup.fromMaybe(""), | 645 scope.injectedScript()->context()->contextId(), objectGroup.fromMaybe(""), |
644 returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), | 646 returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), |
645 std::move(callback)); | 647 std::move(callback)); |
646 } | 648 } |
647 | 649 |
| 650 Response V8RuntimeAgentImpl::startPreciseCoverage() { |
| 651 m_state->setBoolean(V8RuntimeAgentImplState::preciseCoverageStarted, true); |
| 652 v8::debug::Coverage::TogglePrecise(m_inspector->isolate(), true); |
| 653 return Response::OK(); |
| 654 } |
| 655 |
| 656 Response V8RuntimeAgentImpl::stopPreciseCoverage() { |
| 657 m_state->setBoolean(V8RuntimeAgentImplState::preciseCoverageStarted, false); |
| 658 v8::debug::Coverage::TogglePrecise(m_inspector->isolate(), false); |
| 659 return Response::OK(); |
| 660 } |
| 661 |
| 662 namespace { |
| 663 Response takeCoverage( |
| 664 v8::Isolate* isolate, bool reset_count, |
| 665 std::unique_ptr<protocol::Array<protocol::Runtime::ScriptCoverage>>* |
| 666 out_result) { |
| 667 std::unique_ptr<protocol::Array<protocol::Runtime::ScriptCoverage>> result = |
| 668 protocol::Array<protocol::Runtime::ScriptCoverage>::create(); |
| 669 v8::HandleScope handle_scope(isolate); |
| 670 v8::debug::Coverage coverage = |
| 671 v8::debug::Coverage::Collect(isolate, reset_count); |
| 672 for (size_t i = 0; i < coverage.ScriptCount(); i++) { |
| 673 v8::debug::Coverage::ScriptData script_data = coverage.GetScriptData(i); |
| 674 v8::Local<v8::debug::Script> script = script_data.GetScript(); |
| 675 std::unique_ptr<protocol::Array<protocol::Runtime::FunctionCoverage>> |
| 676 functions = |
| 677 protocol::Array<protocol::Runtime::FunctionCoverage>::create(); |
| 678 for (size_t j = 0; j < script_data.FunctionCount(); j++) { |
| 679 v8::debug::Coverage::FunctionData function_data = |
| 680 script_data.GetFunctionData(j); |
| 681 std::unique_ptr<protocol::Array<protocol::Runtime::CoverageRange>> |
| 682 ranges = protocol::Array<protocol::Runtime::CoverageRange>::create(); |
| 683 // At this point we only have per-function coverage data, so there is |
| 684 // only one range per function. |
| 685 ranges->addItem( |
| 686 protocol::Runtime::CoverageRange::create() |
| 687 .setStartLineNumber(function_data.Start().GetLineNumber()) |
| 688 .setStartColumnNumber(function_data.Start().GetColumnNumber()) |
| 689 .setEndLineNumber(function_data.End().GetLineNumber()) |
| 690 .setEndColumnNumber(function_data.End().GetColumnNumber()) |
| 691 .setCount(function_data.Count()) |
| 692 .build()); |
| 693 functions->addItem( |
| 694 protocol::Runtime::FunctionCoverage::create() |
| 695 .setFunctionName(toProtocolString( |
| 696 function_data.Name().FromMaybe(v8::Local<v8::String>()))) |
| 697 .setRanges(std::move(ranges)) |
| 698 .build()); |
| 699 } |
| 700 String16 url; |
| 701 v8::Local<v8::String> name; |
| 702 if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name)) { |
| 703 url = toProtocolString(name); |
| 704 } |
| 705 result->addItem(protocol::Runtime::ScriptCoverage::create() |
| 706 .setScriptId(String16::fromInteger(script->Id())) |
| 707 .setUrl(url) |
| 708 .setFunctions(std::move(functions)) |
| 709 .build()); |
| 710 } |
| 711 *out_result = std::move(result); |
| 712 return Response::OK(); |
| 713 } |
| 714 } // anonymous namespace |
| 715 |
| 716 Response V8RuntimeAgentImpl::takePreciseCoverage( |
| 717 std::unique_ptr<protocol::Array<protocol::Runtime::ScriptCoverage>>* |
| 718 out_result) { |
| 719 if (!m_state->booleanProperty(V8RuntimeAgentImplState::preciseCoverageStarted, |
| 720 false)) { |
| 721 return Response::Error("Precise coverage has not been started."); |
| 722 } |
| 723 return takeCoverage(m_inspector->isolate(), true, out_result); |
| 724 } |
| 725 |
| 726 Response V8RuntimeAgentImpl::getBestEffortCoverage( |
| 727 std::unique_ptr<protocol::Array<protocol::Runtime::ScriptCoverage>>* |
| 728 out_result) { |
| 729 return takeCoverage(m_inspector->isolate(), false, out_result); |
| 730 } |
| 731 |
648 void V8RuntimeAgentImpl::restore() { | 732 void V8RuntimeAgentImpl::restore() { |
649 if (!m_state->booleanProperty(V8RuntimeAgentImplState::runtimeEnabled, false)) | 733 if (!m_state->booleanProperty(V8RuntimeAgentImplState::runtimeEnabled, false)) |
650 return; | 734 return; |
651 m_frontend.executionContextsCleared(); | 735 m_frontend.executionContextsCleared(); |
652 enable(); | 736 enable(); |
653 if (m_state->booleanProperty( | 737 if (m_state->booleanProperty( |
654 V8RuntimeAgentImplState::customObjectFormatterEnabled, false)) | 738 V8RuntimeAgentImplState::customObjectFormatterEnabled, false)) |
655 m_session->setCustomObjectFormatterEnabled(true); | 739 m_session->setCustomObjectFormatterEnabled(true); |
| 740 if (m_state->booleanProperty(V8RuntimeAgentImplState::preciseCoverageStarted, |
| 741 false)) |
| 742 startPreciseCoverage(); |
656 } | 743 } |
657 | 744 |
658 Response V8RuntimeAgentImpl::enable() { | 745 Response V8RuntimeAgentImpl::enable() { |
659 if (m_enabled) return Response::OK(); | 746 if (m_enabled) return Response::OK(); |
660 m_inspector->client()->beginEnsureAllContextsInGroup( | 747 m_inspector->client()->beginEnsureAllContextsInGroup( |
661 m_session->contextGroupId()); | 748 m_session->contextGroupId()); |
662 m_enabled = true; | 749 m_enabled = true; |
663 m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, true); | 750 m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, true); |
664 m_inspector->enableStackCapturingIfNeeded(); | 751 m_inspector->enableStackCapturingIfNeeded(); |
665 m_session->reportAllContexts(this); | 752 m_session->reportAllContexts(this); |
666 V8ConsoleMessageStorage* storage = | 753 V8ConsoleMessageStorage* storage = |
667 m_inspector->ensureConsoleMessageStorage(m_session->contextGroupId()); | 754 m_inspector->ensureConsoleMessageStorage(m_session->contextGroupId()); |
668 for (const auto& message : storage->messages()) { | 755 for (const auto& message : storage->messages()) { |
669 if (!reportMessage(message.get(), false)) break; | 756 if (!reportMessage(message.get(), false)) break; |
670 } | 757 } |
671 return Response::OK(); | 758 return Response::OK(); |
672 } | 759 } |
673 | 760 |
674 Response V8RuntimeAgentImpl::disable() { | 761 Response V8RuntimeAgentImpl::disable() { |
675 if (!m_enabled) return Response::OK(); | 762 if (!m_enabled) return Response::OK(); |
676 m_enabled = false; | 763 m_enabled = false; |
677 m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, false); | 764 m_state->setBoolean(V8RuntimeAgentImplState::runtimeEnabled, false); |
678 m_inspector->disableStackCapturingIfNeeded(); | 765 m_inspector->disableStackCapturingIfNeeded(); |
679 m_session->discardInjectedScripts(); | 766 m_session->discardInjectedScripts(); |
680 reset(); | 767 reset(); |
681 m_inspector->client()->endEnsureAllContextsInGroup( | 768 m_inspector->client()->endEnsureAllContextsInGroup( |
682 m_session->contextGroupId()); | 769 m_session->contextGroupId()); |
| 770 stopPreciseCoverage(); |
683 return Response::OK(); | 771 return Response::OK(); |
684 } | 772 } |
685 | 773 |
686 void V8RuntimeAgentImpl::reset() { | 774 void V8RuntimeAgentImpl::reset() { |
687 m_compiledScripts.clear(); | 775 m_compiledScripts.clear(); |
688 if (m_enabled) { | 776 if (m_enabled) { |
689 if (const V8InspectorImpl::ContextByIdMap* contexts = | 777 if (const V8InspectorImpl::ContextByIdMap* contexts = |
690 m_inspector->contextGroup(m_session->contextGroupId())) { | 778 m_inspector->contextGroup(m_session->contextGroupId())) { |
691 for (auto& idContext : *contexts) idContext.second->setReported(false); | 779 for (auto& idContext : *contexts) idContext.second->setReported(false); |
692 } | 780 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 } | 818 } |
731 | 819 |
732 bool V8RuntimeAgentImpl::reportMessage(V8ConsoleMessage* message, | 820 bool V8RuntimeAgentImpl::reportMessage(V8ConsoleMessage* message, |
733 bool generatePreview) { | 821 bool generatePreview) { |
734 message->reportToFrontend(&m_frontend, m_session, generatePreview); | 822 message->reportToFrontend(&m_frontend, m_session, generatePreview); |
735 m_frontend.flush(); | 823 m_frontend.flush(); |
736 return m_inspector->hasConsoleMessageStorage(m_session->contextGroupId()); | 824 return m_inspector->hasConsoleMessageStorage(m_session->contextGroupId()); |
737 } | 825 } |
738 | 826 |
739 } // namespace v8_inspector | 827 } // namespace v8_inspector |
OLD | NEW |