OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium 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 "platform/v8_inspector/V8Console.h" | 5 #include "platform/v8_inspector/V8Console.h" |
6 | 6 |
7 #include "platform/inspector_protocol/Platform.h" | 7 #include "platform/inspector_protocol/Platform.h" |
8 #include "platform/inspector_protocol/String16.h" | 8 #include "platform/inspector_protocol/String16.h" |
9 #include "platform/v8_inspector/InjectedScript.h" | 9 #include "platform/v8_inspector/InjectedScript.h" |
10 #include "platform/v8_inspector/InspectedContext.h" | 10 #include "platform/v8_inspector/InspectedContext.h" |
(...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 bool success = console->SetPrototype(context, v8::Object::New(isolate)).From
Maybe(false); | 660 bool success = console->SetPrototype(context, v8::Object::New(isolate)).From
Maybe(false); |
661 DCHECK(success); | 661 DCHECK(success); |
662 | 662 |
663 if (hasMemoryAttribute) | 663 if (hasMemoryAttribute) |
664 console->SetAccessorProperty(toV8StringInternalized(isolate, "memory"),
v8::Function::New(isolate, V8Console::memoryGetterCallback, console), v8::Functi
on::New(isolate, V8Console::memorySetterCallback), static_cast<v8::PropertyAttri
bute>(v8::None), v8::DEFAULT); | 664 console->SetAccessorProperty(toV8StringInternalized(isolate, "memory"),
v8::Function::New(isolate, V8Console::memoryGetterCallback, console), v8::Functi
on::New(isolate, V8Console::memorySetterCallback), static_cast<v8::PropertyAttri
bute>(v8::None), v8::DEFAULT); |
665 | 665 |
666 console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::Extern
al::New(isolate, inspectedContext)); | 666 console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::Extern
al::New(isolate, inspectedContext)); |
667 return console; | 667 return console; |
668 } | 668 } |
669 | 669 |
| 670 void V8Console::clearInspectedContextIfNeeded(v8::Local<v8::Context> context, v8
::Local<v8::Object> console) |
| 671 { |
| 672 v8::Isolate* isolate = context->GetIsolate(); |
| 673 console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::Extern
al::New(isolate, nullptr)); |
| 674 } |
| 675 |
670 v8::Local<v8::Object> V8Console::createCommandLineAPI(InspectedContext* inspecte
dContext) | 676 v8::Local<v8::Object> V8Console::createCommandLineAPI(InspectedContext* inspecte
dContext) |
671 { | 677 { |
672 v8::Local<v8::Context> context = inspectedContext->context(); | 678 v8::Local<v8::Context> context = inspectedContext->context(); |
673 v8::Isolate* isolate = context->GetIsolate(); | 679 v8::Isolate* isolate = context->GetIsolate(); |
674 v8::MicrotasksScope microtasksScope(isolate, v8::MicrotasksScope::kDoNotRunM
icrotasks); | 680 v8::MicrotasksScope microtasksScope(isolate, v8::MicrotasksScope::kDoNotRunM
icrotasks); |
675 | 681 |
676 v8::Local<v8::Object> commandLineAPI = v8::Object::New(isolate); | 682 v8::Local<v8::Object> commandLineAPI = v8::Object::New(isolate); |
677 | 683 |
678 createBoundFunctionProperty(context, commandLineAPI, "dir", V8Console::dirCa
llback, "function dir(value) { [Command Line API] }"); | 684 createBoundFunctionProperty(context, commandLineAPI, "dir", V8Console::dirCa
llback, "function dir(value) { [Command Line API] }"); |
679 createBoundFunctionProperty(context, commandLineAPI, "dirxml", V8Console::di
rxmlCallback, "function dirxml(value) { [Command Line API] }"); | 685 createBoundFunctionProperty(context, commandLineAPI, "dirxml", V8Console::di
rxmlCallback, "function dirxml(value) { [Command Line API] }"); |
(...skipping 16 matching lines...) Expand all Loading... |
696 createBoundFunctionProperty(context, commandLineAPI, "$2", V8Console::inspec
tedObject2); | 702 createBoundFunctionProperty(context, commandLineAPI, "$2", V8Console::inspec
tedObject2); |
697 createBoundFunctionProperty(context, commandLineAPI, "$3", V8Console::inspec
tedObject3); | 703 createBoundFunctionProperty(context, commandLineAPI, "$3", V8Console::inspec
tedObject3); |
698 createBoundFunctionProperty(context, commandLineAPI, "$4", V8Console::inspec
tedObject4); | 704 createBoundFunctionProperty(context, commandLineAPI, "$4", V8Console::inspec
tedObject4); |
699 | 705 |
700 inspectedContext->debugger()->client()->installAdditionalCommandLineAPI(cont
ext, commandLineAPI); | 706 inspectedContext->debugger()->client()->installAdditionalCommandLineAPI(cont
ext, commandLineAPI); |
701 | 707 |
702 commandLineAPI->SetPrivate(context, inspectedContextPrivateKey(isolate), v8:
:External::New(isolate, inspectedContext)); | 708 commandLineAPI->SetPrivate(context, inspectedContextPrivateKey(isolate), v8:
:External::New(isolate, inspectedContext)); |
703 return commandLineAPI; | 709 return commandLineAPI; |
704 } | 710 } |
705 | 711 |
706 void V8Console::clearInspectedContextIfNeeded(v8::Local<v8::Context> context, v8
::Local<v8::Object> console) | 712 static bool isCommandLineAPIGetter(const String16& name) |
707 { | 713 { |
708 v8::Isolate* isolate = context->GetIsolate(); | 714 if (name.length() != 2) |
709 console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::Extern
al::New(isolate, nullptr)); | 715 return false; |
| 716 // $0 ... $4, $_ |
| 717 return name[0] == '$' && ((name[1] >= '0' && name[1] <= '4') || name[1] == '
_'); |
710 } | 718 } |
711 | 719 |
712 bool V8Debugger::isCommandLineAPIMethod(const String16& name) | 720 void V8Console::CommandLineAPIScope::accessorGetterCallback(v8::Local<v8::Name>
name, const v8::PropertyCallbackInfo<v8::Value>& info) |
713 { | 721 { |
714 DEFINE_STATIC_LOCAL(protocol::HashSet<String16>, methods, ()); | 722 CommandLineAPIScope* scope = static_cast<CommandLineAPIScope*>(info.Data().A
s<v8::External>()->Value()); |
715 if (methods.size() == 0) { | 723 DCHECK(scope); |
716 const char* members[] = { "dir", "dirxml", "keys", "values", "profile",
"profileEnd", "inspect", | 724 |
717 "copy", "clear", "debug", "undebug", "monitor", "unmonitor", "table"
}; | 725 v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); |
718 for (size_t i = 0; i < PROTOCOL_ARRAY_LENGTH(members); ++i) | 726 if (scope->m_cleanup) { |
719 methods.add(members[i]); | 727 bool removed = info.Holder()->Delete(context, name).FromMaybe(false); |
| 728 DCHECK(removed); |
| 729 return; |
720 } | 730 } |
721 return methods.find(name) != methods.end(); | 731 v8::Local<v8::Object> commandLineAPI = scope->m_commandLineAPI; |
| 732 |
| 733 v8::Local<v8::Value> value; |
| 734 if (!commandLineAPI->Get(context, name).ToLocal(&value)) |
| 735 return; |
| 736 if (isCommandLineAPIGetter(toProtocolStringWithTypeCheck(name))) { |
| 737 DCHECK(value->IsFunction()); |
| 738 v8::MicrotasksScope microtasks(info.GetIsolate(), v8::MicrotasksScope::k
DoNotRunMicrotasks); |
| 739 if (value.As<v8::Function>()->Call(context, commandLineAPI, 0, nullptr).
ToLocal(&value)) |
| 740 info.GetReturnValue().Set(value); |
| 741 } else { |
| 742 info.GetReturnValue().Set(value); |
| 743 } |
722 } | 744 } |
723 | 745 |
724 bool V8Debugger::isCommandLineAPIGetter(const String16& name) | 746 void V8Console::CommandLineAPIScope::accessorSetterCallback(v8::Local<v8::Name>
name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info) |
725 { | 747 { |
726 DEFINE_STATIC_LOCAL(protocol::HashSet<String16>, getters, ()); | 748 CommandLineAPIScope* scope = static_cast<CommandLineAPIScope*>(info.Data().A
s<v8::External>()->Value()); |
727 if (getters.size() == 0) { | 749 v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); |
728 const char* members[] = { "$0", "$1", "$2", "$3", "$4", "$_" }; | 750 if (!info.Holder()->Delete(context, name).FromMaybe(false)) |
729 for (size_t i = 0; i < PROTOCOL_ARRAY_LENGTH(members); ++i) | 751 return; |
730 getters.add(members[i]); | 752 if (!info.Holder()->CreateDataProperty(context, name, value).FromMaybe(false
)) |
| 753 return; |
| 754 bool removed = scope->m_installedMethods->Delete(context, name).FromMaybe(fa
lse); |
| 755 DCHECK(removed); |
| 756 } |
| 757 |
| 758 V8Console::CommandLineAPIScope::CommandLineAPIScope(v8::Local<v8::Context> conte
xt, v8::Local<v8::Object> commandLineAPI, v8::Local<v8::Object> global) |
| 759 : m_context(context) |
| 760 , m_commandLineAPI(commandLineAPI) |
| 761 , m_global(global) |
| 762 , m_installedMethods(v8::Set::New(context->GetIsolate())) |
| 763 , m_cleanup(false) |
| 764 { |
| 765 v8::Local<v8::Array> names; |
| 766 if (!m_commandLineAPI->GetOwnPropertyNames(context).ToLocal(&names)) |
| 767 return; |
| 768 v8::Local<v8::External> externalThis = v8::External::New(context->GetIsolate
(), this); |
| 769 for (size_t i = 0; i < names->Length(); ++i) { |
| 770 v8::Local<v8::Value> name; |
| 771 if (!names->Get(context, i).ToLocal(&name) || !name->IsName()) |
| 772 continue; |
| 773 if (m_global->Has(context, name).FromMaybe(true)) |
| 774 continue; |
| 775 if (!m_installedMethods->Add(context, name).ToLocal(&m_installedMethods)
) |
| 776 continue; |
| 777 if (!m_global->SetAccessor(context, v8::Local<v8::Name>::Cast(name), Com
mandLineAPIScope::accessorGetterCallback, |
| 778 CommandLineAPIScope::accessorSetterCallback, externalThis, |
| 779 v8::DEFAULT, v8::DontEnum).FromMaybe(false)) { |
| 780 bool removed = m_installedMethods->Delete(context, name).FromMaybe(f
alse); |
| 781 DCHECK(removed); |
| 782 continue; |
| 783 } |
731 } | 784 } |
732 return getters.find(name) != getters.end(); | 785 } |
| 786 |
| 787 V8Console::CommandLineAPIScope::~CommandLineAPIScope() |
| 788 { |
| 789 m_cleanup = true; |
| 790 v8::Local<v8::Array> names = m_installedMethods->AsArray(); |
| 791 for (size_t i = 0; i < names->Length(); ++i) { |
| 792 v8::Local<v8::Value> name; |
| 793 if (!names->Get(m_context, i).ToLocal(&name) || !name->IsName()) |
| 794 continue; |
| 795 if (name->IsString()) { |
| 796 v8::Local<v8::Value> descriptor; |
| 797 bool success = m_global->GetOwnPropertyDescriptor(m_context, v8::Loc
al<v8::String>::Cast(name)).ToLocal(&descriptor); |
| 798 DCHECK(success); |
| 799 } |
| 800 } |
733 } | 801 } |
734 | 802 |
735 } // namespace blink | 803 } // namespace blink |
OLD | NEW |