OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "test/inspector-protocol/inspector-impl.h" |
| 6 |
| 7 #include "include/v8.h" |
| 8 #include "src/inspector/string-16.h" |
| 9 #include "src/vector.h" |
| 10 |
| 11 namespace { |
| 12 |
| 13 const int kInspectorClientIndex = v8::Context::kDebugIdIndex + 1; |
| 14 |
| 15 InspectorClientImpl* FromContext(v8::Local<v8::Context> context) { |
| 16 InspectorClientImpl* inspector_client = static_cast<InspectorClientImpl*>( |
| 17 context->GetAlignedPointerFromEmbedderData(kInspectorClientIndex)); |
| 18 CHECK(inspector_client); |
| 19 return inspector_client; |
| 20 } |
| 21 |
| 22 v8_inspector::String16 ToString16(const v8_inspector::StringView& string) { |
| 23 if (string.is8Bit()) |
| 24 return v8_inspector::String16( |
| 25 reinterpret_cast<const char*>(string.characters8()), string.length()); |
| 26 return v8_inspector::String16( |
| 27 reinterpret_cast<const uint16_t*>(string.characters16()), |
| 28 string.length()); |
| 29 } |
| 30 |
| 31 } // namespace |
| 32 |
| 33 void ChannelImpl::SendMessageToFrontend( |
| 34 const v8_inspector::StringView& message) { |
| 35 v8_inspector::String16Builder script; |
| 36 script.append("InspectorTest.dispatchMessage("); |
| 37 script.append(ToString16(message)); |
| 38 script.append(")"); |
| 39 v8_inspector::String16 script_string = script.toString(); |
| 40 frontend_task_runner_->Append(new ExecuteStringTask(v8_inspector::StringView( |
| 41 script_string.characters16(), script_string.length()))); |
| 42 } |
| 43 |
| 44 InspectorClientImpl::InspectorClientImpl() : isolate_(nullptr) {} |
| 45 |
| 46 InspectorClientImpl::~InspectorClientImpl() {} |
| 47 |
| 48 void InspectorClientImpl::connect(ChannelImpl* channel, |
| 49 v8::Local<v8::Context> context) { |
| 50 isolate_ = context->GetIsolate(); |
| 51 |
| 52 inspector_ = v8_inspector::V8Inspector::create(isolate_, this); |
| 53 session_ = inspector_->connect(1, channel, v8_inspector::StringView()); |
| 54 |
| 55 context->SetAlignedPointerInEmbedderData(kInspectorClientIndex, this); |
| 56 inspector_->contextCreated( |
| 57 v8_inspector::V8ContextInfo(context, 1, v8_inspector::StringView())); |
| 58 context_.Reset(isolate_, context); |
| 59 } |
| 60 |
| 61 v8::Local<v8::Context> InspectorClientImpl::ensureDefaultContextInGroup(int) { |
| 62 CHECK(isolate_); |
| 63 return context_.Get(isolate_); |
| 64 } |
| 65 |
| 66 double InspectorClientImpl::currentTimeMS() { |
| 67 return v8::base::OS::TimeCurrentMillis(); |
| 68 } |
| 69 |
| 70 void InspectorClientImpl::runMessageLoopOnPause(int) { |
| 71 TaskRunner* task_runner = TaskRunner::FromContext(context_.Get(isolate_)); |
| 72 CHECK(task_runner); |
| 73 task_runner->RunMessageLoop(true); |
| 74 } |
| 75 |
| 76 void InspectorClientImpl::quitMessageLoopOnPause() { |
| 77 TaskRunner* task_runner = TaskRunner::FromContext(context_.Get(isolate_)); |
| 78 CHECK(task_runner); |
| 79 task_runner->QuitMessageLoop(); |
| 80 } |
| 81 |
| 82 v8_inspector::V8Inspector* InspectorClientImpl::InspectorFromContext( |
| 83 v8::Local<v8::Context> context) { |
| 84 return FromContext(context)->inspector_.get(); |
| 85 } |
| 86 |
| 87 v8_inspector::V8InspectorSession* InspectorClientImpl::SessionFromContext( |
| 88 v8::Local<v8::Context> context) { |
| 89 return FromContext(context)->session_.get(); |
| 90 } |
| 91 |
| 92 ConnectTask::ConnectTask(InspectorClientImpl* client, ChannelImpl* channel, |
| 93 v8::base::Semaphore* ready_semaphore) |
| 94 : client_(client), channel_(channel), ready_semaphore_(ready_semaphore) {} |
| 95 |
| 96 void ConnectTask::Run(v8::Isolate* isolate, |
| 97 const v8::Global<v8::Context>& global_context) { |
| 98 v8::HandleScope handle_scope(isolate); |
| 99 v8::Local<v8::Context> context = global_context.Get(isolate); |
| 100 client_->connect(channel_, context); |
| 101 if (ready_semaphore_) ready_semaphore_->Signal(); |
| 102 } |
| 103 |
| 104 namespace { |
| 105 |
| 106 class ProcessMessageOnBackend : public TaskRunner::Task { |
| 107 public: |
| 108 ProcessMessageOnBackend(const std::string& message) : message_(message) {} |
| 109 |
| 110 bool is_inspector_task() final { return true; } |
| 111 |
| 112 void Run(v8::Isolate* isolate, |
| 113 const v8::Global<v8::Context>& global_context) override { |
| 114 v8_inspector::V8InspectorSession* session = nullptr; |
| 115 { |
| 116 v8::HandleScope handle_scope(isolate); |
| 117 v8::Local<v8::Context> context = global_context.Get(isolate); |
| 118 session = InspectorClientImpl::SessionFromContext(context); |
| 119 CHECK(session); |
| 120 } |
| 121 v8_inspector::StringView message_view( |
| 122 reinterpret_cast<const uint8_t*>(message_.data()), message_.length()); |
| 123 session->dispatchProtocolMessage(message_view); |
| 124 } |
| 125 |
| 126 private: |
| 127 std::string message_; |
| 128 }; |
| 129 |
| 130 } // namespace |
| 131 |
| 132 TaskRunner* FrontendExtension::backend_task_runner_ = nullptr; |
| 133 |
| 134 v8::Local<v8::FunctionTemplate> FrontendExtension::GetNativeFunctionTemplate( |
| 135 v8::Isolate* isolate, v8::Local<v8::String> name) { |
| 136 return v8::FunctionTemplate::New(isolate, |
| 137 FrontendExtension::SendMessageToBackend); |
| 138 } |
| 139 |
| 140 void FrontendExtension::SendMessageToBackend( |
| 141 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 142 CHECK(backend_task_runner_); |
| 143 CHECK(args.Length() == 1 && args[0]->IsString()); |
| 144 std::string message = |
| 145 *v8::String::Utf8Value(v8::Local<v8::String>::Cast(args[0])); |
| 146 backend_task_runner_->Append(new ProcessMessageOnBackend(message)); |
| 147 } |
OLD | NEW |