Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: sky/engine/core/script/dart_controller.cc

Issue 921903002: Add DartController and friends (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: More comment Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium 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 "sky/engine/config.h"
6 #include "sky/engine/core/script/dart_controller.h"
7
8 #include "base/bind.h"
9 #include "base/logging.h"
10 #include "base/single_thread_task_runner.h"
11 #include "sky/engine/bindings2/builtin.h"
12 #include "sky/engine/bindings2/builtin_natives.h"
13 #include "sky/engine/bindings2/builtin_sky.h"
14 #include "sky/engine/core/app/AbstractModule.h"
15 #include "sky/engine/core/app/Module.h"
16 #include "sky/engine/core/dom/Element.h"
17 #include "sky/engine/core/frame/LocalFrame.h"
18 #include "sky/engine/core/html/imports/HTMLImport.h"
19 #include "sky/engine/core/html/imports/HTMLImportChild.h"
20 #include "sky/engine/core/loader/FrameLoaderClient.h"
21 #include "sky/engine/core/script/dart_dependency_catcher.h"
22 #include "sky/engine/core/script/dart_loader.h"
23 #include "sky/engine/core/script/dom_dart_state.h"
24 #include "sky/engine/public/platform/Platform.h"
25 #include "sky/engine/tonic/dart_api_scope.h"
26 #include "sky/engine/tonic/dart_class_library.h"
27 #include "sky/engine/tonic/dart_error.h"
28 #include "sky/engine/tonic/dart_gc_controller.h"
29 #include "sky/engine/tonic/dart_isolate_scope.h"
30 #include "sky/engine/tonic/dart_state.h"
31 #include "sky/engine/wtf/text/TextPosition.h"
32
33 namespace blink {
34
35 #if ENABLE(ASSERT)
36 static const char* kCheckedModeArgs[] = {
37 "--enable_asserts",
38 "--enable_type_checks",
39 "--error_on_bad_type",
40 "--error_on_bad_override",
41 };
42 #endif
43
44 extern const uint8_t* kDartSnapshotBuffer;
45
46 DartController::DartController() : weak_factory_(this) {
47 }
48
49 DartController::~DartController() {
50 }
51
52 void DartController::LoadModule(RefPtr<AbstractModule> module,
53 const String& source,
54 const TextPosition& textPosition) {
55 DartIsolateScope isolate_scope(dart_state()->isolate());
56 DartApiScope dart_api_scope;
57
58 DartDependencyCatcher dependency_catcher(dart_state()->loader());
59
60 Dart_Handle library = Dart_LoadLibrary(
61 StringToDart(dart_state(), module->url()),
62 StringToDart(dart_state(), source), textPosition.m_line.zeroBasedInt(),
63 textPosition.m_column.zeroBasedInt());
64
65 if (LogIfError(library))
66 return;
67
68 if (HTMLImport* parent = module->document()->import()) {
69 for (HTMLImportChild* child = static_cast<HTMLImportChild*>(parent->firstChi ld());
70 child; child = static_cast<HTMLImportChild*>(child->next())) {
71 if (Element* link = child->link()) {
72 String name = link->getAttribute(HTMLNames::asAttr);
73
74 Module* childModule = child->module();
75 if (childModule
76 && childModule->library()
77 && !childModule->library()->is_empty()) {
78 if (LogIfError(Dart_LibraryImportLibrary(
79 library, childModule->library()->dart_value(),
80 StringToDart(dart_state(), name))))
81 return;
82 }
83 }
84 }
85 }
86
87 module->set_library(DartValue::Create(dart_state(), library));
88 const auto& dependencies = dependency_catcher.dependencies();
89
90 if (dependencies.isEmpty()) {
91 ExecuteModule(module);
92 } else {
93 dart_state()->loader().WaitForDependencies(
94 dependencies, base::Bind(&DartController::ExecuteModule,
95 weak_factory_.GetWeakPtr(), module));
96 }
97 }
98
99 void DartController::ExecuteModule(RefPtr<AbstractModule> module) {
100 DCHECK(Dart_CurrentIsolate() == dart_state()->isolate());
101 DartApiScope dart_api_scope;
102
103 LogIfError(Dart_FinalizeLoading(true));
104 Dart_Handle library = module->library()->dart_value();
105 const char* name = module->isApplication() ? "main" : "init";
106 Dart_Handle closure_name = Dart_NewStringFromCString(name);
107 Dart_Handle result = Dart_Invoke(library, closure_name, 0, nullptr);
108
109 if (module->isApplication()) {
110 // TODO(dart): This will throw an API error if main() is absent. It would be
111 // better to test whether main() is present first, then attempt to invoke it
112 // so as to capture & report other errors.
113 LogIfError(result);
114 }
115 }
116
117 static void UnhandledExceptionCallback(Dart_Handle error) {
118 DCHECK(!Dart_IsError(error));
119 LOG(ERROR) << Dart_GetError(error);
120 }
121
122 static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
123 Dart_Handle library,
124 Dart_Handle url) {
125 return DartLoader::HandleLibraryTag(tag, library, url);
126 }
127
128 static void IsolateShutdownCallback(void* callback_data) {
129 // TODO(dart)
130 }
131
132 static bool IsServiceIsolateURL(const char* url_name) {
133 return url_name != nullptr &&
134 String(url_name) == DART_VM_SERVICE_ISOLATE_NAME;
135 }
136
137 // TODO(rafaelw): Right now this only supports the creation of the handle
138 // watcher isolate. Presumably, we'll want application isolates to spawn their
139 // own isolates.
140 static Dart_Isolate IsolateCreateCallback(const char* script_uri,
141 const char* main,
142 const char* package_root,
143 void* callback_data,
144 char** error) {
145
146 if (IsServiceIsolateURL(script_uri)) {
147 return Dart_CreateIsolate(script_uri, "main", kDartSnapshotBuffer, nullptr,
148 error);
149 }
150
151 // Create & start the handle watcher isolate
152 CHECK(kDartSnapshotBuffer);
153 DartState* dart_state = new DartState();
154 Dart_Isolate isolate = Dart_CreateIsolate("sky:handle_watcher", "",
155 kDartSnapshotBuffer, dart_state, error);
156 CHECK(isolate) << error;
157 dart_state->set_isolate(isolate);
158
159 CHECK(!LogIfError(Dart_SetLibraryTagHandler(LibraryTagHandler)));
160
161 {
162 DartApiScope apiScope;
163 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
164 Builtin::SetNativeResolver(Builtin::kMojoCoreLibrary);
165 }
166
167 Dart_ExitIsolate();
168
169 CHECK(Dart_IsolateMakeRunnable(isolate));
170 return isolate;
171 }
172
173 static void CallHandleMessage(base::WeakPtr<DartState> dart_state) {
174 if (!dart_state)
175 return;
176
177 DartIsolateScope scope(dart_state->isolate());
178 DartApiScope api_scope;
179 LogIfError(Dart_HandleMessage());
180 }
181
182 static void MessageNotifyCallback(Dart_Isolate dest_isolate) {
183 DCHECK(Platform::current());
184 Platform::current()->mainThreadTaskRunner()->PostTask(FROM_HERE,
185 base::Bind(&CallHandleMessage, DartState::From(dest_isolate)->GetWeakPtr() ));
186 }
187
188 static void EnsureHandleWatcherStarted() {
189 static bool handle_watcher_started = false;
190 if (handle_watcher_started)
191 return;
192
193 // TODO(dart): Call Dart_Cleanup (ensure the handle watcher isolate is closed)
194 // during shutdown.
195 Dart_Handle mojo_core_lib =
196 Builtin::LoadAndCheckLibrary(Builtin::kMojoCoreLibrary);
197 CHECK(!LogIfError((mojo_core_lib)));
198 Dart_Handle handle_watcher_type = Dart_GetType(
199 mojo_core_lib,
200 Dart_NewStringFromCString("MojoHandleWatcher"),
201 0,
202 nullptr);
203 CHECK(!LogIfError(handle_watcher_type));
204 CHECK(!LogIfError(Dart_Invoke(
205 handle_watcher_type,
206 Dart_NewStringFromCString("_start"),
207 0,
208 nullptr)));
209
210 // RunLoop until the handle watcher isolate is spun-up.
211 CHECK(!LogIfError(Dart_RunLoop()));
212 handle_watcher_started = true;
213 }
214
215 void DartController::CreateIsolateFor(Document* document) {
216 DCHECK(document);
217 CHECK(kDartSnapshotBuffer);
218 char* error = nullptr;
219 dom_dart_state_ = adoptPtr(new DOMDartState(document));
220 Dart_Isolate isolate = Dart_CreateIsolate(
221 document->url().string().utf8().data(), "main", kDartSnapshotBuffer,
222 static_cast<DartState*>(dom_dart_state_.get()), &error);
223 Dart_SetMessageNotifyCallback(MessageNotifyCallback);
224 CHECK(isolate) << error;
225 dom_dart_state_->set_isolate(isolate);
226 Dart_SetGcCallbacks(DartGCPrologue, DartGCEpilogue);
227 CHECK(!LogIfError(Dart_SetLibraryTagHandler(LibraryTagHandler)));
228
229 {
230 DartApiScope apiScope;
231
232 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
233 Builtin::SetNativeResolver(Builtin::kMojoCoreLibrary);
234 BuiltinNatives::Init();
235
236 builtin_sky_ = adoptPtr(new BuiltinSky(dart_state()));
237 dart_state()->class_library().set_provider(builtin_sky_.get());
238 builtin_sky_->InstallWindow(dart_state());
239
240 document->frame()->loaderClient()->didCreateIsolate(isolate);
241
242 EnsureHandleWatcherStarted();
243 }
244 Dart_ExitIsolate();
245 }
246
247 void DartController::ClearForClose() {
248 DartIsolateScope scope(dom_dart_state_->isolate());
249 Dart_ShutdownIsolate();
250 dom_dart_state_.clear();
251 }
252
253 void DartController::InitVM() {
254 int argc = 0;
255 const char** argv = nullptr;
256
257 #if ENABLE(ASSERT)
258 argc = arraysize(kCheckedModeArgs);
259 argv = kCheckedModeArgs;
260 #endif
261
262 CHECK(Dart_SetVMFlags(argc, argv));
263 CHECK(Dart_Initialize(IsolateCreateCallback,
264 nullptr, // Isolate interrupt callback.
265 UnhandledExceptionCallback, IsolateShutdownCallback,
266 // File IO callbacks.
267 nullptr, nullptr, nullptr, nullptr, nullptr));
268 }
269
270 } // namespace blink
OLDNEW
« no previous file with comments | « sky/engine/core/script/dart_controller.h ('k') | sky/engine/core/script/dart_dependency_catcher.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698