| 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/core/script/dart_controller.h" | 5 #include "sky/engine/core/script/dart_controller.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
| 10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| 11 #include "dart/runtime/bin/embedded_dart_io.h" | |
| 12 #include "dart/runtime/include/dart_mirrors_api.h" | |
| 13 #include "gen/sky/platform/RuntimeEnabledFeatures.h" | |
| 14 #include "sky/engine/bindings/builtin.h" | 11 #include "sky/engine/bindings/builtin.h" |
| 15 #include "sky/engine/bindings/builtin_natives.h" | 12 #include "sky/engine/bindings/builtin_natives.h" |
| 16 #include "sky/engine/bindings/builtin_sky.h" | 13 #include "sky/engine/bindings/builtin_sky.h" |
| 17 #include "sky/engine/core/app/AbstractModule.h" | |
| 18 #include "sky/engine/core/app/Module.h" | |
| 19 #include "sky/engine/core/dom/Element.h" | |
| 20 #include "sky/engine/core/frame/LocalFrame.h" | |
| 21 #include "sky/engine/core/loader/FrameLoaderClient.h" | |
| 22 #include "sky/engine/core/script/dart_debugger.h" | 14 #include "sky/engine/core/script/dart_debugger.h" |
| 15 #include "sky/engine/core/script/dart_init.h" |
| 23 #include "sky/engine/core/script/dart_service_isolate.h" | 16 #include "sky/engine/core/script/dart_service_isolate.h" |
| 24 #include "sky/engine/core/script/dom_dart_state.h" | 17 #include "sky/engine/core/script/dom_dart_state.h" |
| 25 #include "sky/engine/public/platform/Platform.h" | 18 #include "sky/engine/public/platform/Platform.h" |
| 26 #include "sky/engine/tonic/dart_api_scope.h" | 19 #include "sky/engine/tonic/dart_api_scope.h" |
| 27 #include "sky/engine/tonic/dart_class_library.h" | 20 #include "sky/engine/tonic/dart_class_library.h" |
| 28 #include "sky/engine/tonic/dart_dependency_catcher.h" | 21 #include "sky/engine/tonic/dart_dependency_catcher.h" |
| 29 #include "sky/engine/tonic/dart_error.h" | 22 #include "sky/engine/tonic/dart_error.h" |
| 30 #include "sky/engine/tonic/dart_gc_controller.h" | 23 #include "sky/engine/tonic/dart_gc_controller.h" |
| 31 #include "sky/engine/tonic/dart_invoke.h" | 24 #include "sky/engine/tonic/dart_invoke.h" |
| 32 #include "sky/engine/tonic/dart_isolate_scope.h" | 25 #include "sky/engine/tonic/dart_isolate_scope.h" |
| 33 #include "sky/engine/tonic/dart_library_loader.h" | 26 #include "sky/engine/tonic/dart_library_loader.h" |
| 34 #include "sky/engine/tonic/dart_snapshot_loader.h" | 27 #include "sky/engine/tonic/dart_snapshot_loader.h" |
| 35 #include "sky/engine/tonic/dart_state.h" | 28 #include "sky/engine/tonic/dart_state.h" |
| 36 #include "sky/engine/tonic/dart_wrappable.h" | 29 #include "sky/engine/tonic/dart_wrappable.h" |
| 37 #include "sky/engine/wtf/text/TextPosition.h" | |
| 38 | 30 |
| 39 namespace blink { | 31 namespace blink { |
| 40 namespace { | 32 namespace { |
| 41 | 33 |
| 42 void CreateEmptyRootLibraryIfNeeded() { | 34 void CreateEmptyRootLibraryIfNeeded() { |
| 43 if (Dart_IsNull(Dart_RootLibrary())) { | 35 if (Dart_IsNull(Dart_RootLibrary())) { |
| 44 Dart_LoadScript(Dart_NewStringFromCString("dart:empty"), Dart_EmptyString(), | 36 Dart_LoadScript(Dart_NewStringFromCString("dart:empty"), Dart_EmptyString(), |
| 45 0, 0); | 37 0, 0); |
| 46 } | 38 } |
| 47 } | 39 } |
| 48 | 40 |
| 41 void CallHandleMessage(base::WeakPtr<DartState> dart_state) { |
| 42 TRACE_EVENT0("sky", "CallHandleMessage"); |
| 43 |
| 44 if (!dart_state) |
| 45 return; |
| 46 |
| 47 DartIsolateScope scope(dart_state->isolate()); |
| 48 DartApiScope api_scope; |
| 49 LogIfError(Dart_HandleMessage()); |
| 50 } |
| 51 |
| 52 void MessageNotifyCallback(Dart_Isolate dest_isolate) { |
| 53 DCHECK(Platform::current()); |
| 54 Platform::current()->mainThreadTaskRunner()->PostTask(FROM_HERE, |
| 55 base::Bind(&CallHandleMessage, DartState::From(dest_isolate)->GetWeakPtr()
)); |
| 56 } |
| 57 |
| 49 } // namespace | 58 } // namespace |
| 50 | 59 |
| 51 #if ENABLE(DART_STRICT) | |
| 52 static const char* kCheckedModeArgs[] = {"--enable_asserts", | |
| 53 "--enable_type_checks", | |
| 54 "--error_on_bad_type", | |
| 55 "--error_on_bad_override", | |
| 56 #if WTF_OS_IOS | |
| 57 "--no-profile" | |
| 58 #endif | |
| 59 }; | |
| 60 #endif | |
| 61 | |
| 62 extern const uint8_t* kDartVmIsolateSnapshotBuffer; | |
| 63 extern const uint8_t* kDartIsolateSnapshotBuffer; | |
| 64 | |
| 65 DartController::DartController() : weak_factory_(this) { | 60 DartController::DartController() : weak_factory_(this) { |
| 66 } | 61 } |
| 67 | 62 |
| 68 DartController::~DartController() { | 63 DartController::~DartController() { |
| 64 if (dom_dart_state_) { |
| 65 // Don't use a DartIsolateScope here since we never exit the isolate. |
| 66 Dart_EnterIsolate(dom_dart_state_->isolate()); |
| 67 Dart_ShutdownIsolate(); |
| 68 dom_dart_state_->SetIsolate(nullptr); |
| 69 dom_dart_state_.clear(); |
| 70 } |
| 69 } | 71 } |
| 70 | 72 |
| 71 void DartController::DidLoadMainLibrary(String name) { | 73 void DartController::DidLoadMainLibrary(String name) { |
| 72 DCHECK(Dart_CurrentIsolate() == dart_state()->isolate()); | 74 DCHECK(Dart_CurrentIsolate() == dart_state()->isolate()); |
| 73 DartApiScope dart_api_scope; | 75 DartApiScope dart_api_scope; |
| 74 | 76 |
| 75 if (LogIfError(Dart_FinalizeLoading(true))) | 77 if (LogIfError(Dart_FinalizeLoading(true))) |
| 76 return; | 78 return; |
| 77 | 79 |
| 78 Dart_Handle library = Dart_LookupLibrary(StringToDart(dart_state(), name)); | 80 Dart_Handle library = Dart_LookupLibrary(StringToDart(dart_state(), name)); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 DartLibraryLoader& loader = dart_state()->library_loader(); | 114 DartLibraryLoader& loader = dart_state()->library_loader(); |
| 113 loader.set_library_provider(library_provider); | 115 loader.set_library_provider(library_provider); |
| 114 | 116 |
| 115 DartDependencyCatcher dependency_catcher(loader); | 117 DartDependencyCatcher dependency_catcher(loader); |
| 116 loader.LoadLibrary(name); | 118 loader.LoadLibrary(name); |
| 117 loader.WaitForDependencies(dependency_catcher.dependencies(), | 119 loader.WaitForDependencies(dependency_catcher.dependencies(), |
| 118 base::Bind(&DartController::DidLoadMainLibrary, | 120 base::Bind(&DartController::DidLoadMainLibrary, |
| 119 weak_factory_.GetWeakPtr(), name)); | 121 weak_factory_.GetWeakPtr(), name)); |
| 120 } | 122 } |
| 121 | 123 |
| 122 static void UnhandledExceptionCallback(Dart_Handle error) { | |
| 123 LOG(ERROR) << Dart_GetError(error); | |
| 124 } | |
| 125 | |
| 126 static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag, | |
| 127 Dart_Handle library, | |
| 128 Dart_Handle url) { | |
| 129 return DartLibraryLoader::HandleLibraryTag(tag, library, url); | |
| 130 } | |
| 131 | |
| 132 static void IsolateShutdownCallback(void* callback_data) { | |
| 133 // TODO(dart) | |
| 134 } | |
| 135 | |
| 136 static bool IsServiceIsolateURL(const char* url_name) { | |
| 137 return url_name != nullptr && | |
| 138 String(url_name) == DART_VM_SERVICE_ISOLATE_NAME; | |
| 139 } | |
| 140 | |
| 141 static void EnsureHandleWatcherStarted() { | |
| 142 static bool handle_watcher_started = false; | |
| 143 if (handle_watcher_started) | |
| 144 return; | |
| 145 | |
| 146 // TODO(dart): Call Dart_Cleanup (ensure the handle watcher isolate is closed) | |
| 147 // during shutdown. | |
| 148 Dart_Handle mojo_core_lib = | |
| 149 Builtin::LoadAndCheckLibrary(Builtin::kMojoInternalLibrary); | |
| 150 CHECK(!LogIfError((mojo_core_lib))); | |
| 151 Dart_Handle handle_watcher_type = Dart_GetType( | |
| 152 mojo_core_lib, | |
| 153 Dart_NewStringFromCString("MojoHandleWatcher"), | |
| 154 0, | |
| 155 nullptr); | |
| 156 CHECK(!LogIfError(handle_watcher_type)); | |
| 157 CHECK(!LogIfError(Dart_Invoke( | |
| 158 handle_watcher_type, | |
| 159 Dart_NewStringFromCString("_start"), | |
| 160 0, | |
| 161 nullptr))); | |
| 162 | |
| 163 // RunLoop until the handle watcher isolate is spun-up. | |
| 164 CHECK(!LogIfError(Dart_RunLoop())); | |
| 165 handle_watcher_started = true; | |
| 166 } | |
| 167 | |
| 168 // TODO(rafaelw): Right now this only supports the creation of the handle | |
| 169 // watcher isolate and the service isolate. Presumably, we'll want application | |
| 170 // isolates to spawn their own isolates. | |
| 171 static Dart_Isolate IsolateCreateCallback(const char* script_uri, | |
| 172 const char* main, | |
| 173 const char* package_root, | |
| 174 Dart_IsolateFlags* flags, | |
| 175 void* callback_data, | |
| 176 char** error) { | |
| 177 if (IsServiceIsolateURL(script_uri)) { | |
| 178 CHECK(kDartIsolateSnapshotBuffer); | |
| 179 DartState* dart_state = new DartState(); | |
| 180 Dart_Isolate isolate = | |
| 181 Dart_CreateIsolate(script_uri, "main", kDartIsolateSnapshotBuffer, | |
| 182 nullptr, nullptr, error); | |
| 183 CHECK(isolate) << error; | |
| 184 dart_state->SetIsolate(isolate); | |
| 185 CHECK(Dart_IsServiceIsolate(isolate)); | |
| 186 CHECK(!LogIfError(Dart_SetLibraryTagHandler(LibraryTagHandler))); | |
| 187 { | |
| 188 DartApiScope apiScope; | |
| 189 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); | |
| 190 Builtin::SetNativeResolver(Builtin::kMojoInternalLibrary); | |
| 191 Builtin::SetNativeResolver(Builtin::kIOLibrary); | |
| 192 BuiltinNatives::Init(BuiltinNatives::DartIOIsolate); | |
| 193 // Start the handle watcher from the service isolate so it isn't available | |
| 194 // for debugging or general Observatory interaction. | |
| 195 EnsureHandleWatcherStarted(); | |
| 196 if (RuntimeEnabledFeatures::observatoryEnabled()) { | |
| 197 std::string ip = "127.0.0.1"; | |
| 198 const intptr_t port = 8181; | |
| 199 const bool service_isolate_booted = | |
| 200 DartServiceIsolate::Startup(ip, port, LibraryTagHandler, error); | |
| 201 CHECK(service_isolate_booted) << error; | |
| 202 } | |
| 203 } | |
| 204 Dart_ExitIsolate(); | |
| 205 return isolate; | |
| 206 } | |
| 207 | |
| 208 // Create & start the handle watcher isolate | |
| 209 CHECK(kDartIsolateSnapshotBuffer); | |
| 210 // TODO(abarth): Who deletes this DartState instance? | |
| 211 DartState* dart_state = new DartState(); | |
| 212 Dart_Isolate isolate = | |
| 213 Dart_CreateIsolate("sky:handle_watcher", "", kDartIsolateSnapshotBuffer, | |
| 214 nullptr, dart_state, error); | |
| 215 CHECK(isolate) << error; | |
| 216 dart_state->SetIsolate(isolate); | |
| 217 | |
| 218 CHECK(!LogIfError(Dart_SetLibraryTagHandler(LibraryTagHandler))); | |
| 219 | |
| 220 { | |
| 221 DartApiScope apiScope; | |
| 222 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); | |
| 223 Builtin::SetNativeResolver(Builtin::kMojoInternalLibrary); | |
| 224 Builtin::SetNativeResolver(Builtin::kIOLibrary); | |
| 225 | |
| 226 if (!script_uri) | |
| 227 CreateEmptyRootLibraryIfNeeded(); | |
| 228 } | |
| 229 | |
| 230 Dart_ExitIsolate(); | |
| 231 | |
| 232 CHECK(Dart_IsolateMakeRunnable(isolate)); | |
| 233 return isolate; | |
| 234 } | |
| 235 | |
| 236 static void CallHandleMessage(base::WeakPtr<DartState> dart_state) { | |
| 237 TRACE_EVENT0("sky", "CallHandleMessage"); | |
| 238 | |
| 239 if (!dart_state) | |
| 240 return; | |
| 241 | |
| 242 DartIsolateScope scope(dart_state->isolate()); | |
| 243 DartApiScope api_scope; | |
| 244 LogIfError(Dart_HandleMessage()); | |
| 245 } | |
| 246 | |
| 247 static void MessageNotifyCallback(Dart_Isolate dest_isolate) { | |
| 248 DCHECK(Platform::current()); | |
| 249 Platform::current()->mainThreadTaskRunner()->PostTask(FROM_HERE, | |
| 250 base::Bind(&CallHandleMessage, DartState::From(dest_isolate)->GetWeakPtr()
)); | |
| 251 } | |
| 252 | |
| 253 void DartController::CreateIsolateFor(PassOwnPtr<DOMDartState> state) { | 124 void DartController::CreateIsolateFor(PassOwnPtr<DOMDartState> state) { |
| 254 CHECK(kDartIsolateSnapshotBuffer); | 125 CHECK(kDartIsolateSnapshotBuffer); |
| 255 char* error = nullptr; | 126 char* error = nullptr; |
| 256 dom_dart_state_ = state; | 127 dom_dart_state_ = state; |
| 257 Dart_Isolate isolate = Dart_CreateIsolate( | 128 Dart_Isolate isolate = Dart_CreateIsolate( |
| 258 dom_dart_state_->url().utf8().data(), "main", kDartIsolateSnapshotBuffer, | 129 dom_dart_state_->url().utf8().data(), "main", kDartIsolateSnapshotBuffer, |
| 259 nullptr, static_cast<DartState*>(dom_dart_state_.get()), &error); | 130 nullptr, static_cast<DartState*>(dom_dart_state_.get()), &error); |
| 260 Dart_SetMessageNotifyCallback(MessageNotifyCallback); | 131 Dart_SetMessageNotifyCallback(MessageNotifyCallback); |
| 261 CHECK(isolate) << error; | 132 CHECK(isolate) << error; |
| 262 dom_dart_state_->SetIsolate(isolate); | 133 dom_dart_state_->SetIsolate(isolate); |
| 263 Dart_SetGcCallbacks(DartGCPrologue, DartGCEpilogue); | 134 Dart_SetGcCallbacks(DartGCPrologue, DartGCEpilogue); |
| 264 CHECK(!LogIfError(Dart_SetLibraryTagHandler(LibraryTagHandler))); | 135 CHECK(!LogIfError(Dart_SetLibraryTagHandler(DartLibraryTagHandler))); |
| 265 | 136 |
| 266 { | 137 { |
| 267 DartApiScope apiScope; | 138 DartApiScope apiScope; |
| 268 | 139 |
| 269 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); | 140 Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); |
| 270 Builtin::SetNativeResolver(Builtin::kMojoInternalLibrary); | 141 Builtin::SetNativeResolver(Builtin::kMojoInternalLibrary); |
| 271 Builtin::SetNativeResolver(Builtin::kIOLibrary); | 142 Builtin::SetNativeResolver(Builtin::kIOLibrary); |
| 272 BuiltinNatives::Init(BuiltinNatives::MainIsolate); | 143 BuiltinNatives::Init(BuiltinNatives::MainIsolate); |
| 273 | 144 |
| 274 builtin_sky_ = adoptPtr(new BuiltinSky(dart_state())); | 145 builtin_sky_ = adoptPtr(new BuiltinSky(dart_state())); |
| 275 dart_state()->class_library().set_provider(builtin_sky_.get()); | 146 dart_state()->class_library().set_provider(builtin_sky_.get()); |
| 276 | 147 |
| 277 if (dart_state()->document()) | 148 if (dart_state()->document()) |
| 278 builtin_sky_->InstallWindow(dart_state()); | 149 builtin_sky_->InstallWindow(dart_state()); |
| 279 | 150 |
| 280 EnsureHandleWatcherStarted(); | 151 EnsureHandleWatcherStarted(); |
| 281 } | 152 } |
| 282 Dart_ExitIsolate(); | 153 Dart_ExitIsolate(); |
| 283 } | 154 } |
| 284 | 155 |
| 285 void DartController::InstallView(View* view) { | 156 void DartController::InstallView(View* view) { |
| 286 DartIsolateScope isolate_scope(dart_state()->isolate()); | 157 DartIsolateScope isolate_scope(dart_state()->isolate()); |
| 287 DartApiScope dart_api_scope; | 158 DartApiScope dart_api_scope; |
| 288 | 159 |
| 289 builtin_sky_->InstallView(view); | 160 builtin_sky_->InstallView(view); |
| 290 } | 161 } |
| 291 | 162 |
| 292 void DartController::ClearForClose() { | |
| 293 // Don't use a DartIsolateScope here since we never exit the isolate. | |
| 294 Dart_EnterIsolate(dom_dart_state_->isolate()); | |
| 295 Dart_ShutdownIsolate(); | |
| 296 dom_dart_state_->SetIsolate(nullptr); | |
| 297 dom_dart_state_.clear(); | |
| 298 } | |
| 299 | |
| 300 void DartController::InitVM() { | |
| 301 int argc = 0; | |
| 302 const char** argv = nullptr; | |
| 303 | |
| 304 #if ENABLE(DART_STRICT) | |
| 305 argc = arraysize(kCheckedModeArgs); | |
| 306 argv = kCheckedModeArgs; | |
| 307 #endif | |
| 308 | |
| 309 dart::bin::BootstrapDartIo(); | |
| 310 | |
| 311 CHECK(Dart_SetVMFlags(argc, argv)); | |
| 312 // This should be called before calling Dart_Initialize. | |
| 313 DartDebugger::InitDebugger(); | |
| 314 CHECK(Dart_Initialize(kDartVmIsolateSnapshotBuffer, | |
| 315 IsolateCreateCallback, | |
| 316 nullptr, // Isolate interrupt callback. | |
| 317 UnhandledExceptionCallback, IsolateShutdownCallback, | |
| 318 // File IO callbacks. | |
| 319 nullptr, nullptr, nullptr, nullptr, nullptr)); | |
| 320 // Wait for load port- ensures handle watcher and service isolates are | |
| 321 // running. | |
| 322 Dart_ServiceWaitForLoadPort(); | |
| 323 } | |
| 324 | |
| 325 } // namespace blink | 163 } // namespace blink |
| OLD | NEW |