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