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 "include/libplatform/libplatform.h" | |
6 #include "include/v8.h" | |
7 | |
8 #include "src/base/platform/platform.h" | |
9 #include "src/flags.h" | |
10 #include "src/utils.h" | |
11 #include "src/vector.h" | |
12 | |
13 #include "test/inspector-protocol/inspector-impl.h" | |
14 #include "test/inspector-protocol/task-runner.h" | |
15 | |
16 namespace { | |
17 | |
18 class UtilsExtension : public v8::Extension { | |
19 public: | |
20 UtilsExtension() | |
21 : v8::Extension("v8_inspector/utils", | |
22 "native function print(); native function quit();") {} | |
23 virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate( | |
24 v8::Isolate* isolate, v8::Local<v8::String> name) { | |
25 v8::Local<v8::Context> context = isolate->GetCurrentContext(); | |
26 if (name->Equals(context, v8::String::NewFromUtf8( | |
27 isolate, "print", v8::NewStringType::kNormal) | |
28 .ToLocalChecked()) | |
29 .FromJust()) { | |
30 return v8::FunctionTemplate::New(isolate, UtilsExtension::Print); | |
31 } else if (name->Equals(context, | |
32 v8::String::NewFromUtf8(isolate, "quit", | |
33 v8::NewStringType::kNormal) | |
34 .ToLocalChecked()) | |
35 .FromJust()) { | |
36 return v8::FunctionTemplate::New(isolate, UtilsExtension::Quit); | |
37 } | |
38 return v8::Local<v8::FunctionTemplate>(); | |
39 } | |
40 | |
41 private: | |
42 static void Print(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
43 for (int i = 0; i < args.Length(); i++) { | |
44 v8::HandleScope handle_scope(args.GetIsolate()); | |
45 if (i != 0) { | |
46 printf(" "); | |
47 } | |
48 | |
49 // Explicitly catch potential exceptions in toString(). | |
50 v8::TryCatch try_catch(args.GetIsolate()); | |
51 v8::Local<v8::Value> arg = args[i]; | |
52 v8::Local<v8::String> str_obj; | |
53 | |
54 if (arg->IsSymbol()) { | |
55 arg = v8::Local<v8::Symbol>::Cast(arg)->Name(); | |
56 } | |
57 if (!arg->ToString(args.GetIsolate()->GetCurrentContext()) | |
58 .ToLocal(&str_obj)) { | |
59 try_catch.ReThrow(); | |
60 return; | |
61 } | |
62 | |
63 v8::String::Utf8Value str(str_obj); | |
64 int n = | |
65 static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout)); | |
66 if (n != str.length()) { | |
67 printf("Error in fwrite\n"); | |
68 Quit(args); | |
69 } | |
70 } | |
71 printf("\n"); | |
72 fflush(stdout); | |
73 } | |
74 | |
75 static void Quit(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
76 fflush(stdout); | |
77 fflush(stderr); | |
78 _exit(0); | |
79 } | |
80 }; | |
81 | |
82 class SetTimeoutTask : public TaskRunner::Task { | |
83 public: | |
84 SetTimeoutTask(v8::Isolate* isolate, v8::Local<v8::Function> function) | |
85 : function_(isolate, function) {} | |
86 virtual ~SetTimeoutTask() {} | |
87 | |
88 bool is_inspector_task() final { return false; } | |
89 | |
90 void Run(v8::Isolate* isolate, | |
91 const v8::Global<v8::Context>& global_context) override { | |
92 v8::MicrotasksScope microtasks_scope(isolate, | |
93 v8::MicrotasksScope::kRunMicrotasks); | |
94 v8::HandleScope handle_scope(isolate); | |
95 v8::Local<v8::Context> context = global_context.Get(isolate); | |
96 v8::Context::Scope context_scope(context); | |
97 | |
98 v8::Local<v8::Function> function = function_.Get(isolate); | |
99 v8::MaybeLocal<v8::Value> result; | |
100 v8_inspector::V8Inspector* inspector = | |
101 InspectorClientImpl::InspectorFromContext(context); | |
102 if (inspector) inspector->willExecuteScript(context, function->ScriptId()); | |
103 result = function->Call(context, context->Global(), 0, nullptr); | |
104 if (inspector) inspector->didExecuteScript(context); | |
105 } | |
106 | |
107 private: | |
108 v8::Global<v8::Function> function_; | |
109 }; | |
110 | |
111 class SetTimeoutExtension : public v8::Extension { | |
112 public: | |
113 SetTimeoutExtension() | |
114 : v8::Extension("v8_inspector/setTimeout", | |
115 "native function setTimeout();") {} | |
116 | |
117 virtual v8::Local<v8::FunctionTemplate> GetNativeFunctionTemplate( | |
118 v8::Isolate* isolate, v8::Local<v8::String> name) { | |
119 return v8::FunctionTemplate::New(isolate, SetTimeoutExtension::SetTimeout); | |
120 } | |
121 | |
122 private: | |
123 static void SetTimeout(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
124 CHECK(args.Length() == 2 && args[1]->IsNumber() && args[0]->IsFunction()); | |
dgozman
2016/09/28 21:03:08
Let's print error message instead.
kozy
2016/09/28 22:12:26
Done.
| |
125 double delay = args[1].As<v8::Number>()->Value(); | |
126 // setTimeout supports only zero delay. | |
127 CHECK(delay == 0.0); | |
dgozman
2016/09/28 21:03:08
ditto
kozy
2016/09/28 22:12:26
Done.
| |
128 v8::Local<v8::Context> context = args.GetIsolate()->GetCurrentContext(); | |
129 TaskRunner::FromContext(context)->Append(new SetTimeoutTask( | |
130 args.GetIsolate(), v8::Local<v8::Function>::Cast(args[0]))); | |
131 } | |
132 }; | |
133 | |
134 v8_inspector::String16 ToString16(const v8_inspector::StringView& string) { | |
135 if (string.is8Bit()) | |
136 return v8_inspector::String16( | |
137 reinterpret_cast<const char*>(string.characters8()), string.length()); | |
138 return v8_inspector::String16( | |
139 reinterpret_cast<const uint16_t*>(string.characters16()), | |
140 string.length()); | |
141 } | |
142 | |
143 class FrontendChannelImpl : public InspectorClientImpl::FrontendChannel { | |
144 public: | |
145 FrontendChannelImpl(TaskRunner* frontend_task_runner) | |
146 : frontend_task_runner_(frontend_task_runner) {} | |
147 virtual ~FrontendChannelImpl() {} | |
148 | |
149 void SendMessageToFrontend(const v8_inspector::StringView& message) final { | |
150 v8_inspector::String16Builder script; | |
151 script.append("InspectorTest.dispatchMessage("); | |
152 script.append(ToString16(message)); | |
153 script.append(")"); | |
154 frontend_task_runner_->Append(new ExecuteStringTask(script.toString())); | |
155 } | |
156 | |
157 private: | |
158 TaskRunner* frontend_task_runner_; | |
159 }; | |
160 | |
161 } // namespace | |
162 | |
163 int main(int argc, char* argv[]) { | |
164 v8::V8::InitializeICUDefaultLocation(argv[0]); | |
165 v8::Platform* platform = v8::platform::CreateDefaultPlatform(); | |
166 v8::V8::InitializePlatform(platform); | |
167 v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true); | |
168 v8::V8::InitializeExternalStartupData(argv[0]); | |
169 v8::V8::Initialize(); | |
170 | |
171 SetTimeoutExtension set_timeout_extension; | |
172 v8::RegisterExtension(&set_timeout_extension); | |
173 UtilsExtension utils_extension; | |
174 v8::RegisterExtension(&utils_extension); | |
175 SendMessageToBackendExtension send_message_to_backend_extension; | |
176 v8::RegisterExtension(&send_message_to_backend_extension); | |
177 | |
178 v8::base::Semaphore ready_semaphore(0); | |
179 | |
180 const char* backend_extensions[] = {"v8_inspector/setTimeout"}; | |
181 v8::ExtensionConfiguration backend_configuration( | |
182 arraysize(backend_extensions), backend_extensions); | |
183 TaskRunner backend_runner(&backend_configuration, &ready_semaphore); | |
184 ready_semaphore.Wait(); | |
185 SendMessageToBackendExtension::set_backend_task_runner(&backend_runner); | |
186 | |
187 const char* frontend_extensions[] = {"v8_inspector/utils", | |
188 "v8_inspector/frontend"}; | |
189 v8::ExtensionConfiguration frontend_configuration( | |
190 arraysize(frontend_extensions), frontend_extensions); | |
191 TaskRunner frontend_runner(&frontend_configuration, &ready_semaphore); | |
192 ready_semaphore.Wait(); | |
193 | |
194 FrontendChannelImpl frontend_channel(&frontend_runner); | |
195 InspectorClientImpl inspector_client(&backend_runner, &frontend_channel, | |
196 &ready_semaphore); | |
197 ready_semaphore.Wait(); | |
198 | |
199 for (int i = 1; i < argc; ++i) { | |
200 if (argv[i][0] == '-') break; | |
201 | |
202 bool exists = false; | |
203 v8::internal::Vector<const char> chars = | |
204 v8::internal::ReadFile(argv[i], &exists, true); | |
205 CHECK(exists); | |
dgozman
2016/09/28 21:03:08
Let's print error message instead of crashing.
kozy
2016/09/28 22:12:26
Done.
| |
206 v8_inspector::String16 source = | |
207 v8_inspector::String16::fromUTF8(chars.start(), chars.length()); | |
208 frontend_runner.Append(new ExecuteStringTask(source)); | |
209 } | |
210 | |
211 frontend_runner.Join(); | |
212 return 0; | |
213 } | |
OLD | NEW |