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/task-runner.h" | |
6 | |
7 namespace { | |
8 | |
9 const int kTaskRunnerIndex = 2; | |
10 | |
11 void ReportUncaughtException(v8::Isolate* isolate, | |
12 const v8::TryCatch& try_catch) { | |
13 CHECK(try_catch.HasCaught()); | |
14 v8::HandleScope handle_scope(isolate); | |
15 std::string message = *v8::String::Utf8Value(try_catch.Message()->Get()); | |
16 fprintf(stderr, "Unhandle exception: %s\n", message.data()); | |
17 } | |
18 | |
19 } // namespace | |
20 | |
21 TaskRunner::TaskRunner(v8::ExtensionConfiguration* extensions, | |
22 v8::base::Semaphore* ready_semaphore) | |
23 : Thread(Options("Task Runner")), | |
24 extensions_(extensions), | |
25 ready_semaphore_(ready_semaphore), | |
26 isolate_(nullptr), | |
27 process_queue_semaphore_(0), | |
28 nested_loop_count_(0) { | |
29 Start(); | |
30 } | |
31 | |
32 TaskRunner::~TaskRunner() { Join(); } | |
33 | |
34 void TaskRunner::InitializeContext() { | |
35 v8::Isolate::CreateParams params; | |
36 params.array_buffer_allocator = | |
37 v8::ArrayBuffer::Allocator::NewDefaultAllocator(); | |
38 isolate_ = v8::Isolate::New(params); | |
39 isolate_->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped); | |
40 v8::Isolate::Scope isolate_scope(isolate_); | |
41 v8::HandleScope handle_scope(isolate_); | |
42 | |
43 v8::Local<v8::ObjectTemplate> global_template = | |
44 v8::ObjectTemplate::New(isolate_); | |
45 v8::Local<v8::Context> context = | |
46 v8::Context::New(isolate_, extensions_, global_template); | |
47 context->SetAlignedPointerInEmbedderData(kTaskRunnerIndex, this); | |
48 context_.Reset(isolate_, context); | |
49 | |
50 if (ready_semaphore_) ready_semaphore_->Signal(); | |
51 } | |
52 | |
53 void TaskRunner::Run() { | |
54 InitializeContext(); | |
55 RunMessageLoop(false); | |
56 } | |
57 | |
58 void TaskRunner::RunMessageLoop(bool only_protocol) { | |
59 int loop_number = ++nested_loop_count_; | |
60 while (nested_loop_count_ == loop_number) { | |
61 TaskRunner::Task* task = GetNext(only_protocol); | |
62 v8::Isolate::Scope isolate_scope(isolate_); | |
63 v8::TryCatch try_catch(isolate_); | |
64 task->Run(isolate_, context_); | |
65 delete task; | |
66 if (try_catch.HasCaught()) { | |
67 ReportUncaughtException(isolate_, try_catch); | |
68 fflush(stdout); | |
69 fflush(stderr); | |
70 _exit(0); | |
71 } | |
72 } | |
73 } | |
74 | |
75 void TaskRunner::QuitMessageLoop() { | |
76 DCHECK(nested_loop_count_ > 0); | |
77 --nested_loop_count_; | |
78 } | |
79 | |
80 void TaskRunner::Append(Task* task) { | |
81 queue_.Enqueue(task); | |
82 process_queue_semaphore_.Signal(); | |
83 } | |
84 | |
85 TaskRunner::Task* TaskRunner::GetNext(bool only_protocol) { | |
86 for (;;) { | |
87 if (only_protocol) { | |
88 Task* task = nullptr; | |
89 if (queue_.Dequeue(&task)) { | |
90 if (task->is_inspector_task()) return task; | |
91 deffered_queue_.Enqueue(task); | |
92 } | |
93 } else { | |
94 Task* task = nullptr; | |
95 if (deffered_queue_.Dequeue(&task)) return task; | |
96 if (queue_.Dequeue(&task)) return task; | |
97 } | |
98 process_queue_semaphore_.Wait(); | |
99 } | |
100 UNREACHABLE(); | |
101 return nullptr; | |
102 } | |
103 | |
104 TaskRunner* TaskRunner::FromContext(v8::Local<v8::Context> context) { | |
105 return static_cast<TaskRunner*>( | |
106 context->GetAlignedPointerFromEmbedderData(kTaskRunnerIndex)); | |
107 } | |
108 | |
109 ExecuteStringTask::ExecuteStringTask(const v8_inspector::String16& expression) | |
110 : expression_(expression) {} | |
111 | |
112 void ExecuteStringTask::Run(v8::Isolate* isolate, | |
113 const v8::Global<v8::Context>& context) { | |
114 v8::MicrotasksScope microtasks_scope(isolate, | |
115 v8::MicrotasksScope::kRunMicrotasks); | |
116 v8::HandleScope handle_scope(isolate); | |
117 v8::Local<v8::Context> local_context = context.Get(isolate); | |
118 v8::Context::Scope context_scope(local_context); | |
119 | |
120 v8::ScriptOrigin origin(v8::String::Empty(isolate)); | |
121 v8::Local<v8::String> source = | |
122 v8::String::NewFromTwoByte(isolate, expression_.characters16(), | |
123 v8::NewStringType::kNormal, | |
124 expression_.length()) | |
125 .ToLocalChecked(); | |
126 | |
127 v8::ScriptCompiler::Source scriptSource(source, origin); | |
128 v8::Local<v8::Script> script; | |
129 if (!v8::ScriptCompiler::Compile(local_context, &scriptSource) | |
130 .ToLocal(&script)) | |
131 return; | |
132 v8::MaybeLocal<v8::Value> result; | |
133 result = script->Run(local_context); | |
134 } | |
135 | |
136 // main to make compiler happy before other patch will be landed. | |
137 int main(int argc, char* argv[]) { return 0; } | |
OLD | NEW |