Chromium Code Reviews| 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/String16.h" | 7 #include "platform/inspector_protocol/String16.h" |
| 8 #include "platform/v8_inspector/InjectedScript.h" | 8 #include "platform/v8_inspector/InjectedScript.h" |
| 9 #include "platform/v8_inspector/InspectedContext.h" | 9 #include "platform/v8_inspector/InspectedContext.h" |
| 10 #include "platform/v8_inspector/V8Compat.h" | 10 #include "platform/v8_inspector/V8Compat.h" |
| (...skipping 648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 659 bool success = console->SetPrototype(context, v8::Object::New(isolate)).From Maybe(false); | 659 bool success = console->SetPrototype(context, v8::Object::New(isolate)).From Maybe(false); |
| 660 DCHECK(success); | 660 DCHECK(success); |
| 661 | 661 |
| 662 if (hasMemoryAttribute) | 662 if (hasMemoryAttribute) |
| 663 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); | 663 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 | 664 |
| 665 console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::Extern al::New(isolate, inspectedContext)); | 665 console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::Extern al::New(isolate, inspectedContext)); |
| 666 return console; | 666 return console; |
| 667 } | 667 } |
| 668 | 668 |
| 669 void V8Console::clearInspectedContextIfNeeded(v8::Local<v8::Context> context, v8 ::Local<v8::Object> console) | |
| 670 { | |
| 671 v8::Isolate* isolate = context->GetIsolate(); | |
| 672 console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::Extern al::New(isolate, nullptr)); | |
| 673 } | |
| 674 | |
| 669 v8::Local<v8::Object> V8Console::createCommandLineAPI(InspectedContext* inspecte dContext) | 675 v8::Local<v8::Object> V8Console::createCommandLineAPI(InspectedContext* inspecte dContext) |
| 670 { | 676 { |
| 671 v8::Local<v8::Context> context = inspectedContext->context(); | 677 v8::Local<v8::Context> context = inspectedContext->context(); |
| 672 v8::Isolate* isolate = context->GetIsolate(); | 678 v8::Isolate* isolate = context->GetIsolate(); |
| 673 v8::MicrotasksScope microtasksScope(isolate, v8::MicrotasksScope::kDoNotRunM icrotasks); | 679 v8::MicrotasksScope microtasksScope(isolate, v8::MicrotasksScope::kDoNotRunM icrotasks); |
| 674 | 680 |
| 675 v8::Local<v8::Object> commandLineAPI = v8::Object::New(isolate); | 681 v8::Local<v8::Object> commandLineAPI = v8::Object::New(isolate); |
| 676 | 682 |
| 677 createBoundFunctionProperty(context, commandLineAPI, "dir", V8Console::dirCa llback, "function dir(value) { [Command Line API] }"); | 683 createBoundFunctionProperty(context, commandLineAPI, "dir", V8Console::dirCa llback, "function dir(value) { [Command Line API] }"); |
| 678 createBoundFunctionProperty(context, commandLineAPI, "dirxml", V8Console::di rxmlCallback, "function dirxml(value) { [Command Line API] }"); | 684 createBoundFunctionProperty(context, commandLineAPI, "dirxml", V8Console::di rxmlCallback, "function dirxml(value) { [Command Line API] }"); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 695 createBoundFunctionProperty(context, commandLineAPI, "$2", V8Console::inspec tedObject2); | 701 createBoundFunctionProperty(context, commandLineAPI, "$2", V8Console::inspec tedObject2); |
| 696 createBoundFunctionProperty(context, commandLineAPI, "$3", V8Console::inspec tedObject3); | 702 createBoundFunctionProperty(context, commandLineAPI, "$3", V8Console::inspec tedObject3); |
| 697 createBoundFunctionProperty(context, commandLineAPI, "$4", V8Console::inspec tedObject4); | 703 createBoundFunctionProperty(context, commandLineAPI, "$4", V8Console::inspec tedObject4); |
| 698 | 704 |
| 699 inspectedContext->debugger()->client()->installAdditionalCommandLineAPI(cont ext, commandLineAPI); | 705 inspectedContext->debugger()->client()->installAdditionalCommandLineAPI(cont ext, commandLineAPI); |
| 700 | 706 |
| 701 commandLineAPI->SetPrivate(context, inspectedContextPrivateKey(isolate), v8: :External::New(isolate, inspectedContext)); | 707 commandLineAPI->SetPrivate(context, inspectedContextPrivateKey(isolate), v8: :External::New(isolate, inspectedContext)); |
| 702 return commandLineAPI; | 708 return commandLineAPI; |
| 703 } | 709 } |
| 704 | 710 |
| 705 void V8Console::clearInspectedContextIfNeeded(v8::Local<v8::Context> context, v8 ::Local<v8::Object> console) | 711 static bool isCommandLineAPIGetter(const String16& name) |
| 706 { | |
| 707 v8::Isolate* isolate = context->GetIsolate(); | |
| 708 console->SetPrivate(context, inspectedContextPrivateKey(isolate), v8::Extern al::New(isolate, nullptr)); | |
| 709 } | |
| 710 | |
| 711 bool V8Debugger::isCommandLineAPIMethod(const String16& name) | |
| 712 { | |
| 713 DEFINE_STATIC_LOCAL(protocol::HashSet<String16>, methods, ()); | |
| 714 if (methods.size() == 0) { | |
| 715 const char* members[] = { "dir", "dirxml", "keys", "values", "profile", "profileEnd", "inspect", | |
| 716 "copy", "clear", "debug", "undebug", "monitor", "unmonitor", "table" }; | |
| 717 for (size_t i = 0; i < WTF_ARRAY_LENGTH(members); ++i) | |
| 718 methods.add(members[i]); | |
| 719 } | |
| 720 return methods.find(name) != methods.end(); | |
| 721 } | |
| 722 | |
| 723 bool V8Debugger::isCommandLineAPIGetter(const String16& name) | |
| 724 { | 712 { |
| 725 DEFINE_STATIC_LOCAL(protocol::HashSet<String16>, getters, ()); | 713 DEFINE_STATIC_LOCAL(protocol::HashSet<String16>, getters, ()); |
| 726 if (getters.size() == 0) { | 714 if (getters.size() == 0) { |
| 727 const char* members[] = { "$0", "$1", "$2", "$3", "$4", "$_" }; | 715 const char* members[] = { "$0", "$1", "$2", "$3", "$4", "$_" }; |
| 728 for (size_t i = 0; i < WTF_ARRAY_LENGTH(members); ++i) | 716 for (size_t i = 0; i < WTF_ARRAY_LENGTH(members); ++i) |
| 729 getters.add(members[i]); | 717 getters.add(members[i]); |
| 730 } | 718 } |
| 731 return getters.find(name) != getters.end(); | 719 return getters.find(name) != getters.end(); |
| 732 } | 720 } |
| 733 | 721 |
| 722 void V8Console::CommandLineAPIScope::accessorGetterCallback(v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) | |
| 723 { | |
| 724 CommandLineAPIScope* scope = static_cast<CommandLineAPIScope*>(info.Data().A s<v8::External>()->Value()); | |
| 725 DCHECK(!scope); | |
|
dgozman
2016/06/01 19:41:28
DCHECK(scope)
kozy
2016/06/02 00:50:42
Done.
| |
| 726 v8::Local<v8::Object> commandLineAPI = scope->m_commandLineAPI; | |
| 727 v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); | |
| 728 | |
| 729 v8::Local<v8::Value> value; | |
| 730 if (!commandLineAPI->Get(context, name).ToLocal(&value)) | |
| 731 return; | |
| 732 | |
| 733 if (isCommandLineAPIGetter(toProtocolStringWithTypeCheck(name)) && value->Is Function()) { | |
|
dgozman
2016/06/01 19:41:28
It must be a function.
kozy
2016/06/02 00:50:42
Done.
| |
| 734 v8::MicrotasksScope microtasks(info.GetIsolate(), v8::MicrotasksScope::k DoNotRunMicrotasks); | |
| 735 if (value.As<v8::Function>()->Call(context, commandLineAPI, 0, nullptr). ToLocal(&value)) | |
| 736 info.GetReturnValue().Set(value); | |
| 737 } else { | |
| 738 info.GetReturnValue().Set(value); | |
| 739 } | |
| 740 } | |
| 741 | |
| 742 void V8Console::CommandLineAPIScope::accessorSetterCallback(v8::Local<v8::Name> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info) | |
| 743 { | |
| 744 CommandLineAPIScope* scope = static_cast<CommandLineAPIScope*>(info.Data().A s<v8::External>()->Value()); | |
| 745 v8::Local<v8::Context> context = info.GetIsolate()->GetCurrentContext(); | |
| 746 if (!info.Holder()->Delete(context, name).FromMaybe(false)) | |
| 747 return; | |
| 748 if (!info.Holder()->CreateDataProperty(context, name, value).FromMaybe(false )) | |
|
dgozman
2016/06/01 19:41:28
Let's add "var dir = 1" to the test.
kozy
2016/06/02 00:50:42
Done.
| |
| 749 return; | |
| 750 bool removed = scope->m_installedMethods->Delete(context, name).FromMaybe(fa lse); | |
| 751 DCHECK(removed); | |
| 752 } | |
| 753 | |
| 754 V8Console::CommandLineAPIScope::CommandLineAPIScope(v8::Local<v8::Context> conte xt, v8::Local<v8::Object> commandLineAPI, v8::Local<v8::Object> global) | |
| 755 : m_context(context) | |
| 756 , m_commandLineAPI(commandLineAPI) | |
| 757 , m_global(global) | |
| 758 , m_installedMethods(v8::Set::New(context->GetIsolate())) | |
| 759 { | |
| 760 v8::Local<v8::Array> names; | |
| 761 if (!m_commandLineAPI->GetOwnPropertyNames(context).ToLocal(&names)) | |
| 762 return; | |
| 763 for (size_t i = 0; i < names->Length(); ++i) { | |
| 764 v8::Local<v8::Value> name; | |
| 765 if (!names->Get(context, i).ToLocal(&name) || !name->IsName()) | |
| 766 continue; | |
| 767 if (m_global->Has(context, name).FromMaybe(true)) | |
|
dgozman
2016/06/01 19:41:28
Do we account for non-enumerable properties here?
kozy
2016/06/02 00:50:42
We don't hide bindings here.
| |
| 768 continue; | |
| 769 if (!m_installedMethods->Add(context, name).ToLocal(&m_installedMethods) ) | |
| 770 continue; | |
| 771 if (!m_global->SetAccessor(context, v8::Local<v8::Name>::Cast(name), Com mandLineAPIScope::accessorGetterCallback, | |
|
dgozman
2016/06/01 19:41:28
name.As<> ?
kozy
2016/06/02 00:50:43
We can't use As for function arguments because it
| |
| 772 CommandLineAPIScope::accessorSetterCallback, v8::External::New(conte xt->GetIsolate(), this), | |
|
dgozman
2016/06/01 19:41:28
Can we have a single external |this| per scope?
kozy
2016/06/02 00:50:43
Done.
| |
| 773 v8::DEFAULT, v8::DontEnum).FromMaybe(false)) { | |
| 774 bool removed = m_installedMethods->Delete(context, name).FromMaybe(f alse); | |
| 775 DCHECK(removed); | |
| 776 continue; | |
| 777 } | |
| 778 } | |
| 779 } | |
| 780 | |
| 781 V8Console::CommandLineAPIScope::~CommandLineAPIScope() | |
| 782 { | |
| 783 v8::Local<v8::Array> names = m_installedMethods->AsArray(); | |
| 784 for (size_t i = 0; i < names->Length(); ++i) { | |
| 785 v8::Local<v8::Value> name; | |
| 786 if (!names->Get(m_context, i).ToLocal(&name) || !name->IsName()) | |
| 787 continue; | |
| 788 bool removed = m_global->Delete(m_context, name).FromMaybe(false); | |
|
dgozman
2016/06/01 19:41:28
Let's try to definePorperty in the test and check
kozy
2016/06/02 00:50:43
Done.
When defineProperty is called with value the
| |
| 789 DCHECK(removed); | |
| 790 } | |
| 791 } | |
| 792 | |
| 734 } // namespace blink | 793 } // namespace blink |
| OLD | NEW |