OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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 "sky/engine/config.h" | 5 #include "sky/engine/config.h" |
6 #include "sky/engine/core/script/dart_controller.h" | 6 #include "sky/engine/core/script/dart_controller.h" |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
11 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
12 #include "dart/runtime/include/dart_mirrors_api.h" | 12 #include "dart/runtime/include/dart_mirrors_api.h" |
13 #include "sky/engine/bindings/builtin.h" | 13 #include "sky/engine/bindings/builtin.h" |
14 #include "sky/engine/bindings/builtin_natives.h" | 14 #include "sky/engine/bindings/builtin_natives.h" |
15 #include "sky/engine/bindings/builtin_sky.h" | 15 #include "sky/engine/bindings/builtin_sky.h" |
16 #include "sky/engine/core/app/AbstractModule.h" | 16 #include "sky/engine/core/app/AbstractModule.h" |
17 #include "sky/engine/core/app/Module.h" | 17 #include "sky/engine/core/app/Module.h" |
18 #include "sky/engine/core/dom/Element.h" | 18 #include "sky/engine/core/dom/Element.h" |
19 #include "sky/engine/core/frame/LocalFrame.h" | 19 #include "sky/engine/core/frame/LocalFrame.h" |
20 #include "sky/engine/core/html/HTMLScriptElement.h" | 20 #include "sky/engine/core/html/HTMLScriptElement.h" |
21 #include "sky/engine/core/html/imports/HTMLImport.h" | 21 #include "sky/engine/core/html/imports/HTMLImport.h" |
22 #include "sky/engine/core/html/imports/HTMLImportChild.h" | 22 #include "sky/engine/core/html/imports/HTMLImportChild.h" |
23 #include "sky/engine/core/loader/FrameLoaderClient.h" | 23 #include "sky/engine/core/loader/FrameLoaderClient.h" |
| 24 #include "sky/engine/core/script/dart_debugger.h" |
24 #include "sky/engine/core/script/dart_dependency_catcher.h" | 25 #include "sky/engine/core/script/dart_dependency_catcher.h" |
25 #include "sky/engine/core/script/dart_loader.h" | 26 #include "sky/engine/core/script/dart_loader.h" |
| 27 #include "sky/engine/core/script/dart_service_isolate.h" |
26 #include "sky/engine/core/script/dom_dart_state.h" | 28 #include "sky/engine/core/script/dom_dart_state.h" |
27 #include "sky/engine/public/platform/Platform.h" | 29 #include "sky/engine/public/platform/Platform.h" |
28 #include "sky/engine/tonic/dart_api_scope.h" | 30 #include "sky/engine/tonic/dart_api_scope.h" |
29 #include "sky/engine/tonic/dart_class_library.h" | 31 #include "sky/engine/tonic/dart_class_library.h" |
30 #include "sky/engine/tonic/dart_error.h" | 32 #include "sky/engine/tonic/dart_error.h" |
31 #include "sky/engine/tonic/dart_gc_controller.h" | 33 #include "sky/engine/tonic/dart_gc_controller.h" |
32 #include "sky/engine/tonic/dart_invoke.h" | 34 #include "sky/engine/tonic/dart_invoke.h" |
33 #include "sky/engine/tonic/dart_isolate_scope.h" | 35 #include "sky/engine/tonic/dart_isolate_scope.h" |
34 #include "sky/engine/tonic/dart_state.h" | 36 #include "sky/engine/tonic/dart_state.h" |
35 #include "sky/engine/tonic/dart_wrappable.h" | 37 #include "sky/engine/tonic/dart_wrappable.h" |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 | 171 |
170 static void IsolateShutdownCallback(void* callback_data) { | 172 static void IsolateShutdownCallback(void* callback_data) { |
171 // TODO(dart) | 173 // TODO(dart) |
172 } | 174 } |
173 | 175 |
174 static bool IsServiceIsolateURL(const char* url_name) { | 176 static bool IsServiceIsolateURL(const char* url_name) { |
175 return url_name != nullptr && | 177 return url_name != nullptr && |
176 String(url_name) == DART_VM_SERVICE_ISOLATE_NAME; | 178 String(url_name) == DART_VM_SERVICE_ISOLATE_NAME; |
177 } | 179 } |
178 | 180 |
| 181 static void EnsureHandleWatcherStarted() { |
| 182 static bool handle_watcher_started = false; |
| 183 if (handle_watcher_started) |
| 184 return; |
| 185 |
| 186 // TODO(dart): Call Dart_Cleanup (ensure the handle watcher isolate is closed) |
| 187 // during shutdown. |
| 188 Dart_Handle mojo_core_lib = |
| 189 Builtin::LoadAndCheckLibrary(Builtin::kMojoInternalLibrary); |
| 190 CHECK(!LogIfError((mojo_core_lib))); |
| 191 Dart_Handle handle_watcher_type = Dart_GetType( |
| 192 mojo_core_lib, |
| 193 Dart_NewStringFromCString("MojoHandleWatcher"), |
| 194 0, |
| 195 nullptr); |
| 196 CHECK(!LogIfError(handle_watcher_type)); |
| 197 CHECK(!LogIfError(Dart_Invoke( |
| 198 handle_watcher_type, |
| 199 Dart_NewStringFromCString("_start"), |
| 200 0, |
| 201 nullptr))); |
| 202 |
| 203 // RunLoop until the handle watcher isolate is spun-up. |
| 204 CHECK(!LogIfError(Dart_RunLoop())); |
| 205 handle_watcher_started = true; |
| 206 } |
| 207 |
179 // TODO(rafaelw): Right now this only supports the creation of the handle | 208 // TODO(rafaelw): Right now this only supports the creation of the handle |
180 // watcher isolate. Presumably, we'll want application isolates to spawn their | 209 // watcher isolate and the service isolate. Presumably, we'll want application |
181 // own isolates. | 210 // isolates to spawn their own isolates. |
182 static Dart_Isolate IsolateCreateCallback(const char* script_uri, | 211 static Dart_Isolate IsolateCreateCallback(const char* script_uri, |
183 const char* main, | 212 const char* main, |
184 const char* package_root, | 213 const char* package_root, |
185 void* callback_data, | 214 void* callback_data, |
186 char** error) { | 215 char** error) { |
187 | 216 |
188 if (IsServiceIsolateURL(script_uri)) { | 217 if (IsServiceIsolateURL(script_uri)) { |
189 return Dart_CreateIsolate(script_uri, "main", kDartIsolateSnapshotBuffer, | 218 CHECK(kDartIsolateSnapshotBuffer); |
190 nullptr, error); | 219 DartState* dart_state = new DartState(); |
| 220 Dart_Isolate isolate = Dart_CreateIsolate(script_uri, |
| 221 "main", |
| 222 kDartIsolateSnapshotBuffer, |
| 223 nullptr, |
| 224 error); |
| 225 CHECK(isolate) << error; |
| 226 dart_state->set_isolate(isolate); |
| 227 CHECK(Dart_IsServiceIsolate(isolate)); |
| 228 CHECK(!LogIfError(Dart_SetLibraryTagHandler(LibraryTagHandler))); |
| 229 { |
| 230 DartApiScope apiScope; |
| 231 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); |
| 232 Builtin::SetNativeResolver(Builtin::kMojoInternalLibrary); |
| 233 Builtin::SetNativeResolver(Builtin::kIOLibrary); |
| 234 BuiltinNatives::Init(false); |
| 235 // Start the handle watcher from the service isolate so it isn't available |
| 236 // for debugging or general Observatory interaction. |
| 237 EnsureHandleWatcherStarted(); |
| 238 std::string ip = "127.0.0.1"; |
| 239 const intptr_t port = 0; // Automatic port assignment. |
| 240 const bool service_isolate_booted = |
| 241 DartServiceIsolate::Startup(ip, port, LibraryTagHandler, error); |
| 242 CHECK(service_isolate_booted) << error; |
| 243 } |
| 244 Dart_ExitIsolate(); |
| 245 return isolate; |
191 } | 246 } |
192 | 247 |
193 // Create & start the handle watcher isolate | 248 // Create & start the handle watcher isolate |
194 CHECK(kDartIsolateSnapshotBuffer); | 249 CHECK(kDartIsolateSnapshotBuffer); |
195 DartState* dart_state = new DartState(); | 250 DartState* dart_state = new DartState(); |
196 Dart_Isolate isolate = Dart_CreateIsolate("sky:handle_watcher", "", | 251 Dart_Isolate isolate = Dart_CreateIsolate("sky:handle_watcher", "", |
197 kDartIsolateSnapshotBuffer, dart_state, error); | 252 kDartIsolateSnapshotBuffer, dart_state, error); |
198 CHECK(isolate) << error; | 253 CHECK(isolate) << error; |
199 dart_state->set_isolate(isolate); | 254 dart_state->set_isolate(isolate); |
200 | 255 |
201 CHECK(!LogIfError(Dart_SetLibraryTagHandler(LibraryTagHandler))); | 256 CHECK(!LogIfError(Dart_SetLibraryTagHandler(LibraryTagHandler))); |
202 | 257 |
203 { | 258 { |
204 DartApiScope apiScope; | 259 DartApiScope apiScope; |
205 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); | 260 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); |
206 Builtin::SetNativeResolver(Builtin::kMojoInternalLibrary); | 261 Builtin::SetNativeResolver(Builtin::kMojoInternalLibrary); |
| 262 Builtin::SetNativeResolver(Builtin::kIOLibrary); |
207 | 263 |
208 // Ensure the isolate has a root library. | 264 // Ensure the isolate has a root library. |
209 Dart_LoadScript(Dart_NewStringFromCString("dart:empty"), | 265 Dart_LoadScript(Dart_NewStringFromCString("dart:empty"), |
210 Dart_NewStringFromCString(""), 0, 0); | 266 Dart_NewStringFromCString(""), 0, 0); |
211 } | 267 } |
212 | 268 |
213 Dart_ExitIsolate(); | 269 Dart_ExitIsolate(); |
214 | 270 |
215 CHECK(Dart_IsolateMakeRunnable(isolate)); | 271 CHECK(Dart_IsolateMakeRunnable(isolate)); |
216 return isolate; | 272 return isolate; |
217 } | 273 } |
218 | 274 |
219 static void CallHandleMessage(base::WeakPtr<DartState> dart_state) { | 275 static void CallHandleMessage(base::WeakPtr<DartState> dart_state) { |
220 TRACE_EVENT0("sky", "CallHandleMessage"); | 276 TRACE_EVENT0("sky", "CallHandleMessage"); |
221 | 277 |
222 if (!dart_state) | 278 if (!dart_state) |
223 return; | 279 return; |
224 | 280 |
225 DartIsolateScope scope(dart_state->isolate()); | 281 DartIsolateScope scope(dart_state->isolate()); |
226 DartApiScope api_scope; | 282 DartApiScope api_scope; |
227 LogIfError(Dart_HandleMessage()); | 283 LogIfError(Dart_HandleMessage()); |
228 } | 284 } |
229 | 285 |
230 static void MessageNotifyCallback(Dart_Isolate dest_isolate) { | 286 static void MessageNotifyCallback(Dart_Isolate dest_isolate) { |
231 DCHECK(Platform::current()); | 287 DCHECK(Platform::current()); |
232 Platform::current()->mainThreadTaskRunner()->PostTask(FROM_HERE, | 288 Platform::current()->mainThreadTaskRunner()->PostTask(FROM_HERE, |
233 base::Bind(&CallHandleMessage, DartState::From(dest_isolate)->GetWeakPtr()
)); | 289 base::Bind(&CallHandleMessage, DartState::From(dest_isolate)->GetWeakPtr()
)); |
234 } | 290 } |
235 | 291 |
236 static void EnsureHandleWatcherStarted() { | |
237 static bool handle_watcher_started = false; | |
238 if (handle_watcher_started) | |
239 return; | |
240 | |
241 // TODO(dart): Call Dart_Cleanup (ensure the handle watcher isolate is closed) | |
242 // during shutdown. | |
243 Dart_Handle mojo_core_lib = | |
244 Builtin::LoadAndCheckLibrary(Builtin::kMojoInternalLibrary); | |
245 CHECK(!LogIfError((mojo_core_lib))); | |
246 Dart_Handle handle_watcher_type = Dart_GetType( | |
247 mojo_core_lib, | |
248 Dart_NewStringFromCString("MojoHandleWatcher"), | |
249 0, | |
250 nullptr); | |
251 CHECK(!LogIfError(handle_watcher_type)); | |
252 CHECK(!LogIfError(Dart_Invoke( | |
253 handle_watcher_type, | |
254 Dart_NewStringFromCString("_start"), | |
255 0, | |
256 nullptr))); | |
257 | |
258 // RunLoop until the handle watcher isolate is spun-up. | |
259 CHECK(!LogIfError(Dart_RunLoop())); | |
260 handle_watcher_started = true; | |
261 } | |
262 | |
263 void DartController::CreateIsolateFor(Document* document) { | 292 void DartController::CreateIsolateFor(Document* document) { |
264 DCHECK(document); | 293 DCHECK(document); |
265 CHECK(kDartIsolateSnapshotBuffer); | 294 CHECK(kDartIsolateSnapshotBuffer); |
266 char* error = nullptr; | 295 char* error = nullptr; |
267 dom_dart_state_ = adoptPtr(new DOMDartState(document)); | 296 dom_dart_state_ = adoptPtr(new DOMDartState(document)); |
268 Dart_Isolate isolate = Dart_CreateIsolate( | 297 Dart_Isolate isolate = Dart_CreateIsolate( |
269 document->url().string().utf8().data(), "main", kDartIsolateSnapshotBuffer
, | 298 document->url().string().utf8().data(), "main", kDartIsolateSnapshotBuffer
, |
270 static_cast<DartState*>(dom_dart_state_.get()), &error); | 299 static_cast<DartState*>(dom_dart_state_.get()), &error); |
271 Dart_SetMessageNotifyCallback(MessageNotifyCallback); | 300 Dart_SetMessageNotifyCallback(MessageNotifyCallback); |
272 CHECK(isolate) << error; | 301 CHECK(isolate) << error; |
273 dom_dart_state_->set_isolate(isolate); | 302 dom_dart_state_->set_isolate(isolate); |
274 Dart_SetGcCallbacks(DartGCPrologue, DartGCEpilogue); | 303 Dart_SetGcCallbacks(DartGCPrologue, DartGCEpilogue); |
275 CHECK(!LogIfError(Dart_SetLibraryTagHandler(LibraryTagHandler))); | 304 CHECK(!LogIfError(Dart_SetLibraryTagHandler(LibraryTagHandler))); |
276 | 305 |
277 { | 306 { |
278 DartApiScope apiScope; | 307 DartApiScope apiScope; |
279 | 308 |
280 // Ensure the isolate has a root library. | 309 // Ensure the isolate has a root library. |
281 Dart_LoadScript(Dart_NewStringFromCString("dart:empty"), | 310 Dart_LoadScript(Dart_NewStringFromCString("dart:empty"), |
282 Dart_NewStringFromCString(""), 0, 0); | 311 Dart_NewStringFromCString(""), 0, 0); |
283 | 312 |
284 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); | 313 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); |
285 Builtin::SetNativeResolver(Builtin::kMojoInternalLibrary); | 314 Builtin::SetNativeResolver(Builtin::kMojoInternalLibrary); |
286 BuiltinNatives::Init(); | 315 Builtin::SetNativeResolver(Builtin::kIOLibrary); |
| 316 BuiltinNatives::Init(true); |
287 | 317 |
288 builtin_sky_ = adoptPtr(new BuiltinSky(dart_state())); | 318 builtin_sky_ = adoptPtr(new BuiltinSky(dart_state())); |
289 dart_state()->class_library().set_provider(builtin_sky_.get()); | 319 dart_state()->class_library().set_provider(builtin_sky_.get()); |
290 builtin_sky_->InstallWindow(dart_state()); | 320 builtin_sky_->InstallWindow(dart_state()); |
291 | 321 |
292 document->frame()->loaderClient()->didCreateIsolate(isolate); | 322 document->frame()->loaderClient()->didCreateIsolate(isolate); |
293 | 323 |
294 EnsureHandleWatcherStarted(); | 324 EnsureHandleWatcherStarted(); |
295 } | 325 } |
296 Dart_ExitIsolate(); | 326 Dart_ExitIsolate(); |
297 } | 327 } |
298 | 328 |
299 void DartController::ClearForClose() { | 329 void DartController::ClearForClose() { |
300 // Don't use a DartIsolateScope here since we never exit the isolate. | 330 // Don't use a DartIsolateScope here since we never exit the isolate. |
301 Dart_EnterIsolate(dom_dart_state_->isolate()); | 331 Dart_EnterIsolate(dom_dart_state_->isolate()); |
302 Dart_ShutdownIsolate(); | 332 Dart_ShutdownIsolate(); |
303 dom_dart_state_.clear(); | 333 dom_dart_state_.clear(); |
304 } | 334 } |
305 | 335 |
306 void DartController::InitVM() { | 336 void DartController::InitVM() { |
307 int argc = 0; | 337 int argc = 0; |
308 const char** argv = nullptr; | 338 const char** argv = nullptr; |
309 | 339 |
310 #if ENABLE(ASSERT) | 340 #if ENABLE(ASSERT) |
311 argc = arraysize(kCheckedModeArgs); | 341 argc = arraysize(kCheckedModeArgs); |
312 argv = kCheckedModeArgs; | 342 argv = kCheckedModeArgs; |
313 #endif | 343 #endif |
314 | 344 |
315 CHECK(Dart_SetVMFlags(argc, argv)); | 345 CHECK(Dart_SetVMFlags(argc, argv)); |
| 346 // This should be called before calling Dart_Initialize. |
| 347 DartDebugger::InitDebugger(); |
316 CHECK(Dart_Initialize(kDartVmIsolateSnapshotBuffer, | 348 CHECK(Dart_Initialize(kDartVmIsolateSnapshotBuffer, |
317 IsolateCreateCallback, | 349 IsolateCreateCallback, |
318 nullptr, // Isolate interrupt callback. | 350 nullptr, // Isolate interrupt callback. |
319 UnhandledExceptionCallback, IsolateShutdownCallback, | 351 UnhandledExceptionCallback, IsolateShutdownCallback, |
320 // File IO callbacks. | 352 // File IO callbacks. |
321 nullptr, nullptr, nullptr, nullptr, nullptr)); | 353 nullptr, nullptr, nullptr, nullptr, nullptr)); |
| 354 // Wait for load port- ensures handle watcher and service isolates are |
| 355 // running. |
| 356 Dart_ServiceWaitForLoadPort(); |
322 } | 357 } |
323 | 358 |
324 } // namespace blink | 359 } // namespace blink |
OLD | NEW |