diff --git a/DEPS b/DEPS index 58e8f4c09be..629f439531c 100644 --- a/DEPS +++ b/DEPS @@ -55,7 +55,7 @@ deps = { Var('fuchsia_git') + '/ftl' + '@' + '0bb3a02301c8a88b494e58c6636fa509525adaa8', 'src/lib/tonic': - Var('fuchsia_git') + '/tonic' + '@' + '8e0776dc4aa1c7fab21b742279ef90527c59b216', + Var('fuchsia_git') + '/tonic' + '@' + '66fc8a71ae54c628537e7f4b2e8bf9304788c19d', 'src/third_party/gtest': Var('fuchsia_git') + '/third_party/gtest' + '@' + 'c00f82917331efbbd27124b537e4ccc915a02b72', diff --git a/sky/engine/core/script/dart_controller.cc b/sky/engine/core/script/dart_controller.cc index 94af2119658..beb2699f07f 100644 --- a/sky/engine/core/script/dart_controller.cc +++ b/sky/engine/core/script/dart_controller.cc @@ -4,22 +4,10 @@ #include "flutter/sky/engine/core/script/dart_controller.h" +#include + #include "dart/runtime/include/dart_tools_api.h" -#include "flutter/tonic/dart_debugger.h" -#include "flutter/tonic/dart_dependency_catcher.h" -#include "flutter/tonic/dart_io.h" -#include "flutter/tonic/dart_library_loader.h" -#include "flutter/tonic/dart_snapshot_loader.h" -#include "flutter/tonic/dart_state.h" #include "flutter/glue/trace_event.h" -#include "lib/tonic/dart_class_library.h" -#include "lib/tonic/dart_message_handler.h" -#include "lib/tonic/dart_wrappable.h" -#include "lib/tonic/logging/dart_error.h" -#include "lib/tonic/logging/dart_invoke.h" -#include "lib/tonic/scopes/dart_api_scope.h" -#include "lib/tonic/scopes/dart_isolate_scope.h" -#include "mojo/public/cpp/system/data_pipe.h" #include "flutter/sky/engine/bindings/dart_mojo_internal.h" #include "flutter/sky/engine/bindings/dart_runtime_hooks.h" #include "flutter/sky/engine/bindings/dart_ui.h" @@ -29,6 +17,20 @@ #include "flutter/sky/engine/public/platform/Platform.h" #include "flutter/sky/engine/public/platform/sky_settings.h" #include "flutter/sky/engine/wtf/MakeUnique.h" +#include "flutter/tonic/dart_debugger.h" +#include "flutter/tonic/dart_io.h" +#include "flutter/tonic/dart_state.h" +#include "lib/ftl/files/directory.h" +#include "lib/ftl/files/path.h" +#include "lib/tonic/dart_class_library.h" +#include "lib/tonic/dart_message_handler.h" +#include "lib/tonic/dart_wrappable.h" +#include "lib/tonic/file_loader/file_loader.h" +#include "lib/tonic/logging/dart_error.h" +#include "lib/tonic/logging/dart_invoke.h" +#include "lib/tonic/scopes/dart_api_scope.h" +#include "lib/tonic/scopes/dart_isolate_scope.h" +#include "mojo/public/cpp/system/data_pipe.h" #ifdef OS_ANDROID #include "flutter/lib/jni/dart_jni.h" @@ -38,6 +40,16 @@ using tonic::LogIfError; using tonic::ToDart; namespace blink { +namespace { + +// TODO(abarth): Consider adding this to //lib/ftl. +std::string ResolvePath(std::string path) { + if (!path.empty() && path[0] == '/') + return path; + return files::SimplifyPath(files::GetCurrentDirectory() + "/" + path); +} + +} // namespace DartController::DartController() : ui_dart_state_(nullptr) {} @@ -53,6 +65,9 @@ DartController::~DartController() { } bool DartController::SendStartMessage(Dart_Handle root_library) { + if (LogIfError(root_library)) + return true; + { // Temporarily exit the isolate while we make it runnable. Dart_Isolate isolate = dart_state()->isolate(); @@ -93,67 +108,30 @@ bool DartController::SendStartMessage(Dart_Handle root_library) { return LogIfError(result); } -void DartController::DidLoadMainLibrary(std::string name) { - FTL_DCHECK(Dart_CurrentIsolate() == dart_state()->isolate()); - tonic::DartApiScope dart_api_scope; - - FTL_CHECK(!LogIfError(Dart_FinalizeLoading(true))); - - Dart_Handle library = Dart_LookupLibrary(ToDart(name)); - if (LogIfError(library)) - exit(1); - if (SendStartMessage(library)) - exit(1); -} - -void DartController::DidLoadSnapshot() { - TRACE_EVENT0("flutter", "DartController::DidLoadSnapshot"); - - FTL_DCHECK(Dart_CurrentIsolate() == nullptr); - snapshot_loader_ = nullptr; - - Dart_Isolate isolate = dart_state()->isolate(); - tonic::DartIsolateScope isolate_scope(isolate); - tonic::DartApiScope dart_api_scope; - Dart_Handle library = Dart_RootLibrary(); - if (LogIfError(library)) - exit(1); - if (SendStartMessage(library)) - exit(1); -} - void DartController::RunFromPrecompiledSnapshot() { - DidLoadSnapshot(); + TRACE_EVENT0("flutter", "DartController::RunFromPrecompiledSnapshot"); + FTL_DCHECK(Dart_CurrentIsolate() == nullptr); + tonic::DartState::Scope scope(dart_state()); + if (SendStartMessage(Dart_RootLibrary())) + exit(1); } -void DartController::RunFromSnapshot( - mojo::ScopedDataPipeConsumerHandle snapshot) { - snapshot_loader_ = WTF::MakeUnique(dart_state()); - snapshot_loader_->LoadSnapshot(snapshot.Pass(), - [this]() { DidLoadSnapshot(); }); -} - -void DartController::RunFromSnapshotBuffer(const uint8_t* buffer, size_t size) { - DartState::Scope scope(dart_state()); +void DartController::RunFromSnapshot(const uint8_t* buffer, size_t size) { + tonic::DartState::Scope scope(dart_state()); LogIfError(Dart_LoadScriptFromSnapshot(buffer, size)); - Dart_Handle library = Dart_RootLibrary(); - if (LogIfError(library)) - exit(1); - if (SendStartMessage(library)) + if (SendStartMessage(Dart_RootLibrary())) exit(1); } -void DartController::RunFromLibrary(std::string name, - DartLibraryProvider* library_provider) { - DartState::Scope scope(dart_state()); - - DartLibraryLoader& loader = dart_state()->library_loader(); - loader.set_library_provider(library_provider); - - DartDependencyCatcher dependency_catcher(loader); - loader.LoadScript(name); - loader.WaitForDependencies(dependency_catcher.dependencies(), - [this, name]() { DidLoadMainLibrary(name); }); +void DartController::RunFromSource(const std::string& main, + const std::string& packages) { + tonic::DartState::Scope scope(dart_state()); + tonic::FileLoader& loader = dart_state()->file_loader(); + if (!packages.empty() && !loader.LoadPackagesMap(ResolvePath(packages))) + FTL_LOG(WARNING) << "Failed to load package map: " << packages; + LogIfError(loader.LoadScript(main)); + if (SendStartMessage(Dart_RootLibrary())) + exit(1); } void DartController::CreateIsolateFor(std::unique_ptr state) { @@ -164,15 +142,15 @@ void DartController::CreateIsolateFor(std::unique_ptr state) { nullptr, static_cast(state.get()), &error); FTL_CHECK(isolate) << error; ui_dart_state_ = state.release(); - auto& message_handler = dart_state()->message_handler(); FTL_DCHECK(Platform::current()); - message_handler.Initialize( + dart_state()->message_handler().Initialize( ftl::RefPtr(Platform::current()->GetUITaskRunner())); Dart_SetShouldPauseOnStart(SkySettings::Get().start_paused); ui_dart_state_->SetIsolate(isolate); - FTL_CHECK(!LogIfError(Dart_SetLibraryTagHandler(DartLibraryTagHandler))); + FTL_CHECK(!LogIfError( + Dart_SetLibraryTagHandler(tonic::DartState::HandleLibraryTag))); { tonic::DartApiScope dart_api_scope; diff --git a/sky/engine/core/script/dart_controller.h b/sky/engine/core/script/dart_controller.h index 2913955959e..a7b60bd7f9d 100644 --- a/sky/engine/core/script/dart_controller.h +++ b/sky/engine/core/script/dart_controller.h @@ -13,8 +13,6 @@ namespace blink { class UIDartState; -class DartLibraryProvider; -class DartSnapshotLoader; class DartController { public: @@ -23,27 +21,21 @@ class DartController { static void InitVM(); - void RunFromLibrary(std::string name, DartLibraryProvider* library_provider); void RunFromPrecompiledSnapshot(); - void RunFromSnapshot(mojo::ScopedDataPipeConsumerHandle snapshot); - void RunFromSnapshotBuffer(const uint8_t* buffer, size_t size); + void RunFromSnapshot(const uint8_t* buffer, size_t size); + void RunFromSource(const std::string& main, const std::string& packages); void CreateIsolateFor(std::unique_ptr ui_dart_state); - void Shutdown(); UIDartState* dart_state() const { return ui_dart_state_; } private: - void DidLoadMainLibrary(std::string url); - void DidLoadSnapshot(); bool SendStartMessage(Dart_Handle root_library); // The DartState associated with the main isolate. This will be deleted // during isolate shutdown. UIDartState* ui_dart_state_; - std::unique_ptr snapshot_loader_; - FTL_DISALLOW_COPY_AND_ASSIGN(DartController); }; } diff --git a/sky/engine/core/script/dart_init.cc b/sky/engine/core/script/dart_init.cc index 7a6a37a74b9..41d80a8de15 100644 --- a/sky/engine/core/script/dart_init.cc +++ b/sky/engine/core/script/dart_init.cc @@ -16,10 +16,7 @@ #include "dart/runtime/include/dart_mirrors_api.h" #include "flutter/assets/zip_asset_store.h" #include "flutter/tonic/dart_debugger.h" -#include "flutter/tonic/dart_dependency_catcher.h" #include "flutter/tonic/dart_io.h" -#include "flutter/tonic/dart_library_loader.h" -#include "flutter/tonic/dart_snapshot_loader.h" #include "flutter/tonic/dart_state.h" #include "flutter/glue/trace_event.h" #include "lib/ftl/files/eintr_wrapper.h" @@ -70,12 +67,6 @@ namespace blink { const char kSnapshotAssetKey[] = "snapshot_blob.bin"; -Dart_Handle DartLibraryTagHandler(Dart_LibraryTag tag, - Dart_Handle library, - Dart_Handle url) { - return DartLibraryLoader::HandleLibraryTag(tag, library, url); -} - namespace { static const char* kDartProfilingArgs[] = { @@ -192,7 +183,8 @@ Dart_Isolate ServiceIsolateCreateCallback(const char* script_uri, FTL_CHECK(isolate) << error; dart_state->SetIsolate(isolate); FTL_CHECK(Dart_IsServiceIsolate(isolate)); - FTL_CHECK(!LogIfError(Dart_SetLibraryTagHandler(DartLibraryTagHandler))); + FTL_CHECK(!LogIfError( + Dart_SetLibraryTagHandler(tonic::DartState::HandleLibraryTag))); { tonic::DartApiScope dart_api_scope; DartIO::InitForIsolate(); @@ -205,8 +197,8 @@ Dart_Isolate ServiceIsolateCreateCallback(const char* script_uri, const intptr_t port = settings.observatory_port; const bool disable_websocket_origin_check = false; const bool service_isolate_booted = DartServiceIsolate::Startup( - ip, port, DartLibraryTagHandler, IsRunningPrecompiledCode(), - disable_websocket_origin_check, error); + ip, port, tonic::DartState::HandleLibraryTag, + IsRunningPrecompiledCode(), disable_websocket_origin_check, error); FTL_CHECK(service_isolate_booted) << error; } @@ -260,8 +252,8 @@ Dart_Isolate IsolateCreateCallback(const char* script_uri, nullptr, dart_state, error); FTL_CHECK(isolate) << error; dart_state->SetIsolate(isolate); - - FTL_CHECK(!LogIfError(Dart_SetLibraryTagHandler(DartLibraryTagHandler))); + FTL_CHECK(!LogIfError( + Dart_SetLibraryTagHandler(tonic::DartState::HandleLibraryTag))); { tonic::DartApiScope dart_api_scope; diff --git a/sky/engine/core/script/dart_init.h b/sky/engine/core/script/dart_init.h index fee3cdc3ef0..d8c5eb9044d 100644 --- a/sky/engine/core/script/dart_init.h +++ b/sky/engine/core/script/dart_init.h @@ -67,9 +67,6 @@ void SetServiceIsolateHook(ServiceIsolateHook hook); void SetRegisterNativeServiceProtocolExtensionHook( RegisterNativeServiceProtocolExtensionHook hook); -Dart_Handle DartLibraryTagHandler(Dart_LibraryTag tag, - Dart_Handle library, - Dart_Handle url); } // namespace blink #endif // SKY_ENGINE_CORE_SCRIPT_DART_INIT_H_ diff --git a/sky/engine/public/sky/sky_view.cc b/sky/engine/public/sky/sky_view.cc index c67845ae3e2..3176e62b001 100644 --- a/sky/engine/public/sky/sky_view.cc +++ b/sky/engine/public/sky/sky_view.cc @@ -18,8 +18,7 @@ std::unique_ptr SkyView::Create(SkyViewClient* client) { return std::unique_ptr(new SkyView(client)); } -SkyView::SkyView(SkyViewClient* client) - : client_(client) {} +SkyView::SkyView(SkyViewClient* client) : client_(client) {} SkyView::~SkyView() {} @@ -67,19 +66,6 @@ void SkyView::CreateView(const std::string& script_uri) { GetWindow()->UpdateLocale(language_code_, country_code_); } -void SkyView::RunFromLibrary(const std::string& name, - DartLibraryProvider* library_provider) { - dart_controller_->RunFromLibrary(name, library_provider); -} - -void SkyView::RunFromPrecompiledSnapshot() { - dart_controller_->RunFromPrecompiledSnapshot(); -} - -void SkyView::RunFromSnapshot(mojo::ScopedDataPipeConsumerHandle snapshot) { - dart_controller_->RunFromSnapshot(snapshot.Pass()); -} - void SkyView::BeginFrame(ftl::TimePoint frame_time) { GetWindow()->BeginFrame(frame_time); } @@ -123,5 +109,4 @@ Dart_Port SkyView::GetMainPort() { return dart_controller_->dart_state()->main_port(); } - } // namespace blink diff --git a/sky/engine/public/sky/sky_view.h b/sky/engine/public/sky/sky_view.h index 454a3d1501c..54b35217659 100644 --- a/sky/engine/public/sky/sky_view.h +++ b/sky/engine/public/sky/sky_view.h @@ -43,11 +43,7 @@ class SkyView : public WindowClient, public IsolateClient { void BeginFrame(ftl::TimePoint frame_time); void CreateView(const std::string& script_uri); - - void RunFromLibrary(const std::string& name, - DartLibraryProvider* library_provider); - void RunFromPrecompiledSnapshot(); - void RunFromSnapshot(mojo::ScopedDataPipeConsumerHandle snapshot); + DartController* dart_controller() const { return dart_controller_.get(); } void HandlePointerPacket(const pointer::PointerPacketPtr& packet); diff --git a/sky/shell/ui/engine.cc b/sky/shell/ui/engine.cc index 45e496b75f8..e219a48630d 100644 --- a/sky/shell/ui/engine.cc +++ b/sky/shell/ui/engine.cc @@ -6,14 +6,16 @@ #include +#include + #include "flutter/assets/directory_asset_bundle.h" #include "flutter/assets/zip_asset_bundle.h" -#include "flutter/tonic/dart_library_provider_files.h" #include "flutter/glue/movable_wrapper.h" #include "flutter/glue/trace_event.h" #include "lib/ftl/files/path.h" #include "mojo/public/cpp/application/connect.h" #include "flutter/sky/engine/bindings/mojo_services.h" +#include "flutter/sky/engine/core/script/dart_controller.h" #include "flutter/sky/engine/core/script/dart_init.h" #include "flutter/sky/engine/core/script/ui_dart_state.h" #include "flutter/sky/engine/public/platform/Platform.h" @@ -83,25 +85,20 @@ void Engine::BeginFrame(ftl::TimePoint frame_time) { void Engine::RunFromSource(const std::string& main, const std::string& packages, - const std::string& assets_directory) { + const std::string& bundle) { TRACE_EVENT0("flutter", "Engine::RunFromSource"); - // Assets. - ConfigureDirectoryAssetBundle(assets_directory); - // .packages. std::string packages_path = packages; if (packages_path.empty()) packages_path = FindPackagesPath(main); - DartLibraryProviderFiles* provider = new DartLibraryProviderFiles(); - dart_library_provider_.reset(provider); - if (!packages_path.empty()) - provider->LoadPackagesMap(packages_path); - RunFromLibrary(main); + if (!bundle.empty()) + ConfigureDirectoryAssetBundle(bundle); + ConfigureView(main); + sky_view_->dart_controller()->RunFromSource(main, packages_path); } Dart_Port Engine::GetUIIsolateMainPort() { - if (!sky_view_) { + if (!sky_view_) return ILLEGAL_PORT; - } return sky_view_->GetMainPort(); } @@ -183,34 +180,24 @@ void Engine::OnPointerPacket(pointer::PointerPacketPtr packet) { sky_view_->HandlePointerPacket(packet); } -void Engine::RunFromLibrary(const std::string& name) { - TRACE_EVENT0("flutter", "Engine::RunFromLibrary"); - sky_view_ = blink::SkyView::Create(this); - sky_view_->CreateView(name); - sky_view_->RunFromLibrary(name, dart_library_provider_.get()); - sky_view_->SetViewportMetrics(viewport_metrics_); - sky_view_->SetLocale(language_code_, country_code_); - if (!initial_route_.empty()) - sky_view_->PushRoute(initial_route_); -} - void Engine::RunFromSnapshotStream( const std::string& script_uri, mojo::ScopedDataPipeConsumerHandle snapshot) { TRACE_EVENT0("flutter", "Engine::RunFromSnapshotStream"); - sky_view_ = blink::SkyView::Create(this); - sky_view_->CreateView(script_uri); - sky_view_->RunFromSnapshot(snapshot.Pass()); - sky_view_->SetViewportMetrics(viewport_metrics_); - sky_view_->SetLocale(language_code_, country_code_); - if (!initial_route_.empty()) - sky_view_->PushRoute(initial_route_); + ConfigureView(script_uri); + snapshot_drainer_.reset(new glue::DrainDataPipeJob( + std::move(snapshot), [this](std::vector snapshot) { + FTL_DCHECK(sky_view_); + FTL_DCHECK(sky_view_->dart_controller()); + sky_view_->dart_controller()->RunFromSnapshot( + reinterpret_cast(snapshot.data()), snapshot.size()); + })); } -void Engine::ConfigureZipAssetBundle(const mojo::String& path) { +void Engine::ConfigureZipAssetBundle(const std::string& path) { asset_store_ = ftl::MakeRefCounted( - path.get(), ftl::RefPtr( - blink::Platform::current()->GetIOTaskRunner())); + path, ftl::RefPtr( + blink::Platform::current()->GetIOTaskRunner())); new blink::ZipAssetBundle(mojo::GetProxy(&root_bundle_), asset_store_); } @@ -221,43 +208,32 @@ void Engine::ConfigureDirectoryAssetBundle(const std::string& path) { blink::Platform::current()->GetIOTaskRunner())); } -void Engine::RunFromPrecompiledSnapshot(const mojo::String& bundle_path) { - TRACE_EVENT0("flutter", "Engine::RunFromPrecompiledSnapshot"); - - ConfigureZipAssetBundle(bundle_path); - +void Engine::ConfigureView(const std::string& script_uri) { + snapshot_drainer_.reset(); sky_view_ = blink::SkyView::Create(this); - sky_view_->CreateView("http://localhost"); - sky_view_->RunFromPrecompiledSnapshot(); + sky_view_->CreateView(std::move(script_uri)); sky_view_->SetViewportMetrics(viewport_metrics_); sky_view_->SetLocale(language_code_, country_code_); if (!initial_route_.empty()) sky_view_->PushRoute(initial_route_); } +void Engine::RunFromPrecompiledSnapshot(const mojo::String& bundle_path) { + TRACE_EVENT0("flutter", "Engine::RunFromPrecompiledSnapshot"); + ConfigureZipAssetBundle(bundle_path.get()); + ConfigureView("http://localhost"); + sky_view_->dart_controller()->RunFromPrecompiledSnapshot(); +} + void Engine::RunFromFile(const mojo::String& main, const mojo::String& packages, const mojo::String& bundle) { - TRACE_EVENT0("flutter", "Engine::RunFromFile"); - std::string main_dart(main); - if (bundle.size() != 0) { - // The specification of an FLX bundle is optional. - ConfigureZipAssetBundle(bundle); - } - std::string packages_path = packages; - if (packages_path.empty()) - packages_path = FindPackagesPath(main_dart); - DartLibraryProviderFiles* provider = new DartLibraryProviderFiles(); - dart_library_provider_.reset(provider); - if (!packages_path.empty()) - provider->LoadPackagesMap(packages_path); - RunFromLibrary(main_dart); + RunFromSource(main, packages, bundle); } void Engine::RunFromBundle(const mojo::String& script_uri, const mojo::String& path) { TRACE_EVENT0("flutter", "Engine::RunFromBundle"); - ConfigureZipAssetBundle(path); mojo::DataPipe pipe; asset_store_->GetAsStream(blink::kSnapshotAssetKey, diff --git a/sky/shell/ui/engine.h b/sky/shell/ui/engine.h index d894571460f..949aa04e3e2 100644 --- a/sky/shell/ui/engine.h +++ b/sky/shell/ui/engine.h @@ -6,6 +6,13 @@ #define SKY_SHELL_UI_ENGINE_H_ #include "flutter/assets/zip_asset_store.h" +#include "flutter/glue/drain_data_pipe_job.h" +#include "flutter/services/engine/sky_engine.mojom.h" +#include "flutter/services/rasterizer/rasterizer.mojom.h" +#include "flutter/sky/engine/public/sky/sky_view_client.h" +#include "flutter/sky/engine/public/sky/sky_view.h" +#include "flutter/sky/shell/rasterizer.h" +#include "flutter/sky/shell/ui_delegate.h" #include "lib/ftl/macros.h" #include "lib/ftl/memory/weak_ptr.h" #include "lib/ftl/tasks/task_runner.h" @@ -16,12 +23,6 @@ #include "mojo/public/cpp/system/handle.h" #include "mojo/public/interfaces/application/service_provider.mojom.h" #include "mojo/services/asset_bundle/interfaces/asset_bundle.mojom.h" -#include "flutter/sky/engine/public/sky/sky_view_client.h" -#include "flutter/sky/engine/public/sky/sky_view.h" -#include "flutter/services/engine/sky_engine.mojom.h" -#include "flutter/services/rasterizer/rasterizer.mojom.h" -#include "flutter/sky/shell/rasterizer.h" -#include "flutter/sky/shell/ui_delegate.h" #include "third_party/skia/include/core/SkPicture.h" namespace sky { @@ -51,7 +52,7 @@ class Engine : public UIDelegate, void RunFromSource(const std::string& main, const std::string& packages, - const std::string& assets_directory); + const std::string& bundle); Dart_Port GetUIIsolateMainPort(); @@ -91,7 +92,6 @@ class Engine : public UIDelegate, void BindToServiceProvider( mojo::InterfaceRequest request); - void RunFromLibrary(const std::string& name); void RunFromSnapshotStream(const std::string& script_uri, mojo::ScopedDataPipeConsumerHandle snapshot); @@ -100,8 +100,9 @@ class Engine : public UIDelegate, void StopAnimator(); void StartAnimatorIfPossible(); - void ConfigureZipAssetBundle(const mojo::String& path); + void ConfigureZipAssetBundle(const std::string& path); void ConfigureDirectoryAssetBundle(const std::string& path); + void ConfigureView(const std::string& script_uri); Config config_; std::unique_ptr animator_; @@ -112,9 +113,10 @@ class Engine : public UIDelegate, mojo::BindingSet service_provider_bindings_; mojo::asset_bundle::AssetBundlePtr root_bundle_; - std::unique_ptr dart_library_provider_; std::unique_ptr sky_view_; + std::unique_ptr snapshot_drainer_; + std::string initial_route_; ViewportMetricsPtr viewport_metrics_; std::string language_code_; diff --git a/snapshotter/main.cc b/snapshotter/main.cc index 89ca0d0bf0d..9ca4a6c7518 100644 --- a/snapshotter/main.cc +++ b/snapshotter/main.cc @@ -116,16 +116,7 @@ tonic::FileLoader& GetLoader() { Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle url) { - FTL_CHECK(Dart_IsLibrary(library)); - FTL_CHECK(Dart_IsString(url)); - tonic::FileLoader& loader = GetLoader(); - if (tag == Dart_kCanonicalizeUrl) - return loader.CanonicalizeURL(library, url); - if (tag == Dart_kImportTag) - return loader.Import(url); - if (tag == Dart_kSourceTag) - return loader.Source(library, url); - return Dart_NewApiError("Unknown library tag."); + return GetLoader().HandleLibraryTag(tag, library, url); } std::vector CreateSnapshot() { diff --git a/tonic/BUILD.gn b/tonic/BUILD.gn index 8478fc2d2ef..61de7e75390 100644 --- a/tonic/BUILD.gn +++ b/tonic/BUILD.gn @@ -6,31 +6,15 @@ source_set("tonic") { sources = [ "dart_debugger.cc", "dart_debugger.h", - "dart_dependency_catcher.cc", - "dart_dependency_catcher.h", "dart_io.cc", "dart_io.h", - "dart_isolate_reloader.cc", - "dart_isolate_reloader.h", - "dart_library_loader.cc", - "dart_library_loader.h", - "dart_library_provider.cc", - "dart_library_provider.h", - "dart_library_provider_files.cc", - "dart_library_provider_files.h", - "dart_snapshot_loader.cc", - "dart_snapshot_loader.h", "dart_state.cc", "dart_state.h", ] deps = [ - "//base", "//dart/runtime/bin:embedded_dart_io", - "//flutter/glue", - "//lib/tonic/parsers", - "//mojo/data_pipe_utils", - "//mojo/public/cpp/system", + "//lib/ftl", ] public_deps = [ diff --git a/tonic/dart_dependency_catcher.cc b/tonic/dart_dependency_catcher.cc deleted file mode 100644 index f6eec6793fc..00000000000 --- a/tonic/dart_dependency_catcher.cc +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/tonic/dart_dependency_catcher.h" - -#include "flutter/tonic/dart_library_loader.h" - -namespace blink { - -DartDependencyCatcher::DartDependencyCatcher(DartLibraryLoader& loader) - : loader_(loader) { - loader_.set_dependency_catcher(this); -} - -DartDependencyCatcher::~DartDependencyCatcher() { - loader_.set_dependency_catcher(nullptr); -} - -void DartDependencyCatcher::AddDependency(DartDependency* dependency) { - dependencies_.insert(dependency); -} - -} // namespace blink diff --git a/tonic/dart_dependency_catcher.h b/tonic/dart_dependency_catcher.h deleted file mode 100644 index 740c5e2fd13..00000000000 --- a/tonic/dart_dependency_catcher.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_TONIC_DART_DEPENDENCY_CATCHER_H_ -#define FLUTTER_TONIC_DART_DEPENDENCY_CATCHER_H_ - -#include - -#include "lib/ftl/macros.h" - -namespace blink { -class DartLibraryLoader; - -// A base class to represent a dependency. -class DartDependency {}; - -// To catch the dependencies for a library, put a DartDependencyCatcher on the -// stack during the call to Dart_LoadLibrary. -class DartDependencyCatcher { - public: - explicit DartDependencyCatcher(DartLibraryLoader& loader); - ~DartDependencyCatcher(); - - void AddDependency(DartDependency* dependency); - const std::unordered_set& dependencies() const { - return dependencies_; - } - - private: - DartLibraryLoader& loader_; - std::unordered_set dependencies_; - - FTL_DISALLOW_COPY_AND_ASSIGN(DartDependencyCatcher); -}; - -} // namespace blink - -#endif // FLUTTER_TONIC_DART_DEPENDENCY_CATCHER_H_ diff --git a/tonic/dart_isolate_reloader.cc b/tonic/dart_isolate_reloader.cc deleted file mode 100644 index d4bddee30b2..00000000000 --- a/tonic/dart_isolate_reloader.cc +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/tonic/dart_isolate_reloader.h" - -#include - -#include "flutter/tonic/dart_dependency_catcher.h" -#include "flutter/tonic/dart_library_loader.h" -#include "flutter/tonic/dart_library_provider.h" -#include "flutter/tonic/dart_state.h" -#include "flutter/glue/drain_data_pipe_job.h" -#include "flutter/glue/thread.h" -#include "lib/ftl/logging.h" -#include "lib/ftl/synchronization/monitor.h" -#include "lib/tonic/converter/dart_converter.h" -#include "lib/tonic/logging/dart_error.h" -#include "lib/tonic/scopes/dart_api_scope.h" -#include "lib/tonic/scopes/dart_isolate_scope.h" - -using tonic::ToDart; -using tonic::StdStringToDart; -using tonic::StdStringFromDart; - -namespace blink { - -// As each source file is loaded, a LoadResult is queued to be processed on the -// isolate's thread. A LoadResult contains the payload or an error message. -class DartIsolateReloader::LoadResult { - public: - // Successful load result. - LoadResult(intptr_t tag, - const std::string& url, - const std::string& library_url, - const std::string& resolved_url, - std::vector payload) - : success_(true), - tag_(tag), - url_(url), - library_url_(library_url), - resolved_url_(resolved_url), - payload_(std::move(payload)) { - FTL_DCHECK(success()); - } - - // Error load result. - LoadResult(intptr_t tag, - const std::string& url, - const std::string& library_url, - const std::string& error) - : success_(false), - tag_(tag), - url_(url), - library_url_(library_url), - error_(error) {} - - bool success() const { return success_; } - - Dart_Handle Finish() { - if (!success()) { - return StdStringToDart(error_); - } - Dart_Handle uri = StdStringToDart(url_); - Dart_Handle resolved_uri = Dart_Null(); - if (!resolved_url_.empty()) { - resolved_uri = StdStringToDart(resolved_url_); - } - Dart_Handle library = Dart_Null(); - if (!library_url_.empty()) { - library = Dart_LookupLibrary(StdStringToDart(library_url_)); - } - Dart_Handle source = Dart_NewStringFromUTF8( - reinterpret_cast(payload_.data()), payload_.size()); - Dart_Handle result = Dart_Null(); - switch (tag_) { - case Dart_kImportTag: - result = Dart_LoadLibrary(uri, resolved_uri, source, 0, 0); - break; - case Dart_kSourceTag: - result = Dart_LoadSource(library, uri, resolved_uri, source, 0, 0); - break; - case Dart_kScriptTag: - result = Dart_LoadScript(uri, resolved_uri, source, 0, 0); - break; - } - - if (Dart_IsError(result)) { - return result; - } - return Dart_Null(); - } - - private: - bool success_; - intptr_t tag_; - std::string url_; - std::string library_url_; - std::string resolved_url_; - std::string error_; - std::vector payload_; -}; - -DartIsolateReloader::DartIsolateReloader(DartLibraryProvider* library_provider) - : thread_("DartIsolateReloader"), - library_provider_(library_provider), - load_error_(Dart_Null()), - pending_requests_(0) { - FTL_CHECK(thread_.Start()); -} - -DartIsolateReloader::~DartIsolateReloader() {} - -void DartIsolateReloader::SendRequest(Dart_LibraryTag tag, - Dart_Handle url, - Dart_Handle library_url) { - ftl::RefPtr runner = thread_.task_runner(); - std::string url_string = StdStringFromDart(url); - std::string library_url_string = StdStringFromDart(library_url); - - ftl::MonitorLocker locker(&monitor_); - - // Post a task to the worker thread. This task will request the I/O and - // post a LoadResult to be processed once complete. - runner->PostTask([this, tag, url_string, library_url_string]() { - RequestTask(library_provider_, this, static_cast(tag), url_string, - library_url_string); - }); - - pending_requests_++; -} - -void DartIsolateReloader::PostResult(std::unique_ptr load_result) { - ftl::MonitorLocker locker(&monitor_); - pending_requests_--; - load_results_.push(std::move(load_result)); - locker.Signal(); -} - -// As each source file is requested, a LoadRequest is queued to be processed on -// worker thread. -class DartIsolateReloader::LoadRequest { - public: - LoadRequest(DartLibraryProvider* library_provider, - DartIsolateReloader* isolate_reloader, - intptr_t tag, - const std::string& url, - const std::string& library_url) - : isolate_reloader_(isolate_reloader), - tag_(tag), - url_(url), - library_url_(library_url) { - auto stream = library_provider->GetLibraryAsStream(url_); - OnStreamAvailable(std::move(stream.handle), std::move(stream.resolved_url)); - } - - protected: - void OnStreamAvailable(mojo::ScopedDataPipeConsumerHandle handle, - std::string resolved_url) { - if (!handle.is_valid()) { - std::unique_ptr result( - new DartIsolateReloader::LoadResult( - tag_, url_, library_url_, - "File " + url_ + " could not be read.")); - FTL_LOG(ERROR) << "Load failed for " << url_; - isolate_reloader_->PostResult(std::move(result)); - // We are finished with this request. - delete this; - return; - } - resolved_url_ = std::move(resolved_url); - drainer_.reset(new glue::DrainDataPipeJob( - std::move(handle), [this](std::vector buffer) { - std::unique_ptr result( - new DartIsolateReloader::LoadResult( - tag_, url_, library_url_, resolved_url_, std::move(buffer))); - isolate_reloader_->PostResult(std::move(result)); - // We are finished with this request. - delete this; - })); - } - - private: - DartIsolateReloader* isolate_reloader_; - intptr_t tag_; - std::string url_; - std::string library_url_; - std::string resolved_url_; - std::vector buffer_; - std::unique_ptr drainer_; -}; - -void DartIsolateReloader::RequestTask(DartLibraryProvider* library_provider, - DartIsolateReloader* isolate_reloader, - intptr_t tag, - const std::string& url, - const std::string& library_url) { - FTL_DCHECK(isolate_reloader); - FTL_DCHECK(library_provider); - FTL_DCHECK(tag > 0); - // Construct a new LoadRequest. The pointer is dropped here because - // the request deletes itself on success and failure. - new LoadRequest(library_provider, isolate_reloader, tag, url, library_url); -} - -void DartIsolateReloader::HandleLoadResultLocked(LoadResult* load_result) { - if (load_error_ != Dart_Null()) { - // Already have a sticky error. Just drop this result. - return; - } - - // Drop the lock temporarily around the call to Finish because it may - // trigger a recursive call into the tag handler. - monitor_.Exit(); - Dart_Handle error_or_null = load_result->Finish(); - monitor_.Enter(); - - if (!Dart_IsNull(error_or_null)) { - // Set sticky error. - load_error_ = error_or_null; - } -} - -void DartIsolateReloader::ProcessResultQueueLocked() { - while (load_results_.size() > 0) { - // Grab the first load result. - std::unique_ptr result = std::move(load_results_.front()); - load_results_.pop(); - HandleLoadResultLocked(result.get()); - } -} - -bool DartIsolateReloader::IsCompleteLocked() { - return (pending_requests_ == 0) && load_results_.empty(); -} - -bool DartIsolateReloader::BlockUntilComplete() { - ftl::MonitorLocker locker(&monitor_); - - while (true) { - ProcessResultQueueLocked(); - - if (IsCompleteLocked()) { - break; - } - - // Wait to be notified about new I/O results. - locker.Wait(); - } - return !Dart_IsNull(load_error_); -} - -Dart_Handle DartIsolateReloader::HandleLibraryTag(Dart_LibraryTag tag, - Dart_Handle library, - Dart_Handle url) { - if (tag == Dart_kCanonicalizeUrl) { - // Pass through to actual tag handler. - return DartLibraryLoader::HandleLibraryTag(tag, library, url); - } - DartState* dart_state = DartState::Current(); - FTL_DCHECK(dart_state); - DartIsolateReloader* isolate_reloader = dart_state->isolate_reloader(); - // The first call into the tag handler ends up blocking the calling thread - // until the entire reload has completed. All other calls into the - // tag handler schedule requests and return immediately. - const bool blocking_call = (tag == Dart_kScriptTag); - if (!isolate_reloader) { - // The first call into this tag handler must be for the script. - FTL_DCHECK(tag == Dart_kScriptTag); - // Associate the reloader with the isolate. The reloader is owned - // by the dart_state. - dart_state->set_isolate_reloader( - std::unique_ptr(new DartIsolateReloader( - dart_state->library_loader().library_provider()))); - // Get a pointer to the reloader. - isolate_reloader = dart_state->isolate_reloader(); - // Switch the tag handler. - Dart_SetLibraryTagHandler(DartIsolateReloader::HandleLibraryTag); - } else { - // We should not see another request for the script. - FTL_DCHECK(tag != Dart_kScriptTag); - } - - // Issue I/O request. - isolate_reloader->SendRequest(tag, url, (library != Dart_Null()) - ? Dart_LibraryUrl(library) - : Dart_Null()); - - if (blocking_call) { - // Block and process LoadResults until the load is complete. - const bool load_error = isolate_reloader->BlockUntilComplete(); - // Grab the (possibly null) load error from the reloader before its gone. - Dart_Handle result = isolate_reloader->load_error_; - // The reloader will be deleted once we call set_isolate_reloader below. - isolate_reloader = nullptr; - // Disassociate reloader from the isolate, this causes it to be deleted. - dart_state->set_isolate_reloader(nullptr); - Dart_SetLibraryTagHandler(DartLibraryLoader::HandleLibraryTag); - if (load_error) { - // If we hit an error, return the load error. - return result; - } else { - // Finalize loading. - result = Dart_FinalizeLoading(true); - if (Dart_IsError(result)) { - // If we hit an error, return the load error. - return result; - } - } - } - - return Dart_Null(); -} - -} // namespace blink diff --git a/tonic/dart_isolate_reloader.h b/tonic/dart_isolate_reloader.h deleted file mode 100644 index e546fb99ee7..00000000000 --- a/tonic/dart_isolate_reloader.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_TONIC_DART_ISOLATE_RELOADER_H_ -#define FLUTTER_TONIC_DART_ISOLATE_RELOADER_H_ - -#include -#include -#include - -#include "dart/runtime/include/dart_api.h" -#include "flutter/glue/thread.h" -#include "lib/ftl/macros.h" -#include "lib/ftl/synchronization/monitor.h" - -namespace blink { -class DartLibraryProvider; - -// Reloading an isolate must be an atomic operation, meaning, no other tasks -// can run while reloading. A nested run loop is not sufficient because other -// tasks that invoke Dart code can be run. When |HandleLibraryTag| is invoked -// the calling thread will be blocked until the load has fully completed. To -// avoid relying on the message loop we use our own queue and notification -// mechanism. -class DartIsolateReloader { - public: - // The |DartLibraryProvider| used to load the library sources. - DartIsolateReloader(DartLibraryProvider* library_provider); - ~DartIsolateReloader(); - - static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, - Dart_Handle library, - Dart_Handle url); - - private: - class LoadRequest; - class LoadResult; - - void SendRequest(Dart_LibraryTag tag, - Dart_Handle url, - Dart_Handle library_url); - - void PostResult(std::unique_ptr load_result); - - static void RequestTask(DartLibraryProvider* library_provider, - DartIsolateReloader* isolate_reloader, - intptr_t tag, - const std::string& url, - const std::string& library_url); - - void HandleLoadResultLocked(LoadResult* load_result); - void ProcessResultQueueLocked(); - bool IsCompleteLocked(); - bool BlockUntilComplete(); - - glue::Thread thread_; - DartLibraryProvider* library_provider_; - - ftl::Monitor monitor_; - // The monitor is used to protect the following fields: - Dart_Handle load_error_; - std::queue> load_results_; - intptr_t pending_requests_; - - FTL_DISALLOW_COPY_AND_ASSIGN(DartIsolateReloader); -}; - -} // namespace blink - -#endif // FLUTTER_TONIC_DART_ISOLATE_RELOADER_H_ diff --git a/tonic/dart_library_loader.cc b/tonic/dart_library_loader.cc deleted file mode 100644 index b4c69ec6e48..00000000000 --- a/tonic/dart_library_loader.cc +++ /dev/null @@ -1,335 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/tonic/dart_library_loader.h" - -#include - -#include "flutter/tonic/dart_dependency_catcher.h" -#include "flutter/tonic/dart_isolate_reloader.h" -#include "flutter/tonic/dart_library_provider.h" -#include "flutter/tonic/dart_state.h" -#include "flutter/glue/drain_data_pipe_job.h" -#include "flutter/glue/trace_event.h" -#include "lib/tonic/converter/dart_converter.h" -#include "lib/tonic/dart_persistent_value.h" -#include "lib/tonic/logging/dart_error.h" -#include "lib/tonic/scopes/dart_api_scope.h" -#include "lib/tonic/scopes/dart_isolate_scope.h" - -using tonic::StdStringFromDart; -using tonic::ToDart; - -namespace blink { - -namespace { - -// Helper to erase a T* from a container of std::unique_ptrs. -template -void EraseUniquePtr(C& container, T* item) { - std::unique_ptr key = std::unique_ptr(item); - container.erase(key); - key.release(); -} - -} // namespace - -// A DartLibraryLoader::Job represents a network load. It fetches data from the -// network and buffers the data in std::vector. To cancel the job, delete this -// object. -class DartLibraryLoader::Job : public DartDependency { - public: - Job(DartLibraryLoader* loader, const std::string& name) - : loader_(loader), name_(name) { - auto stream = loader->library_provider()->GetLibraryAsStream(name); - OnStreamAvailable(std::move(stream.handle), std::move(stream.resolved_url)); - } - - const std::string& name() const { return name_; } - const std::string& resolved_url() const { return resolved_url_; } - - protected: - DartLibraryLoader* loader_; - - virtual void OnDataAvailable(std::vector buffer) = 0; - - private: - void OnStreamAvailable(mojo::ScopedDataPipeConsumerHandle pipe, - const std::string& resolved_url) { - if (!pipe.is_valid()) { - loader_->DidFailJob(this); - return; - } - resolved_url_ = resolved_url; - drainer_.reset(new glue::DrainDataPipeJob( - std::move(pipe), [this](std::vector buffer) { - OnDataAvailable(std::move(buffer)); - })); - } - - std::string name_; - std::string resolved_url_; - std::unique_ptr drainer_; -}; - -class DartLibraryLoader::ImportJob : public Job { - public: - ImportJob(DartLibraryLoader* loader, - const std::string& name, - bool should_load_as_script) - : Job(loader, name), should_load_as_script_(should_load_as_script) { - TRACE_EVENT_ASYNC_BEGIN1("flutter", "DartLibraryLoader::ImportJob", this, - "url", name); - } - - bool should_load_as_script() const { return should_load_as_script_; } - - private: - void OnDataAvailable(std::vector buffer) override { - TRACE_EVENT_ASYNC_END0("flutter", "DartLibraryLoader::ImportJob", this); - loader_->DidCompleteImportJob(this, std::move(buffer)); - } - - bool should_load_as_script_; -}; - -class DartLibraryLoader::SourceJob : public Job { - public: - SourceJob(DartLibraryLoader* loader, - const std::string& name, - Dart_Handle library) - : Job(loader, name), library_(loader->dart_state(), library) { - TRACE_EVENT_ASYNC_BEGIN1("flutter", "DartLibraryLoader::SourceJob", this, - "url", name); - } - - Dart_PersistentHandle library() const { return library_.value(); } - - private: - void OnDataAvailable(std::vector buffer) override { - TRACE_EVENT_ASYNC_END0("flutter", "DartLibraryLoader::SourceJob", this); - loader_->DidCompleteSourceJob(this, std::move(buffer)); - } - - tonic::DartPersistentValue library_; -}; - -// A DependencyWatcher represents a request to watch for when a given set of -// dependencies (either libraries or parts of libraries) have finished loading. -// When the dependencies are satisfied (including transitive dependencies), then -// the |callback| will be invoked. -class DartLibraryLoader::DependencyWatcher { - public: - DependencyWatcher(const std::unordered_set& dependencies, - const ftl::Closure& callback) - : dependencies_(dependencies), callback_(callback) { - FTL_DCHECK(!dependencies_.empty()); - } - - bool DidResolveDependency( - DartDependency* resolved_dependency, - const std::unordered_set& new_dependencies) { - const auto& it = dependencies_.find(resolved_dependency); - if (it == dependencies_.end()) - return false; - dependencies_.erase(it); - for (const auto& dependency : new_dependencies) - dependencies_.insert(dependency); - return dependencies_.empty(); - } - - const ftl::Closure& callback() const { return callback_; } - - private: - std::unordered_set dependencies_; - ftl::Closure callback_; -}; - -// A WatcherSignaler is responsible for signaling DependencyWatchers when their -// dependencies resolve and for calling the DependencyWatcher's callback. We use -// a separate object of this task because we want to carefully manage when we -// call the callbacks, which can call into us again reentrantly. -// -// WatcherSignaler is designed to be placed on the stack as a RAII. After its -// destructor runs, we might have executed aribitrary script. -class DartLibraryLoader::WatcherSignaler { - public: - WatcherSignaler(DartLibraryLoader& loader, - DartDependency* resolved_dependency) - : loader_(loader), - catcher_(new DartDependencyCatcher(loader)), - resolved_dependency_(resolved_dependency) {} - - ~WatcherSignaler() { - std::vector completed_watchers; - for (const auto& watcher : loader_.dependency_watchers_) { - if (watcher->DidResolveDependency(resolved_dependency_, - catcher_->dependencies())) - completed_watchers.push_back(watcher.get()); - } - - // Notice that we remove the dependency catcher and extract all the - // callbacks before running any of them. We don't want to be re-entered - // below the callbacks and end up in an inconsistent state. - catcher_ = nullptr; - std::vector callbacks; - for (const auto& watcher : completed_watchers) { - callbacks.push_back(watcher->callback()); - EraseUniquePtr(loader_.dependency_watchers_, watcher); - } - - // Finally, run all the callbacks while touching only data on the stack. - for (const auto& callback : callbacks) - callback(); - } - - private: - DartLibraryLoader& loader_; - std::unique_ptr catcher_; - DartDependency* resolved_dependency_; -}; - -DartLibraryLoader::DartLibraryLoader(DartState* dart_state) - : dart_state_(dart_state), - library_provider_(nullptr), - dependency_catcher_(nullptr) {} - -DartLibraryLoader::~DartLibraryLoader() {} - -Dart_Handle DartLibraryLoader::HandleLibraryTag(Dart_LibraryTag tag, - Dart_Handle library, - Dart_Handle url) { - FTL_DCHECK(Dart_IsLibrary(library) || Dart_IsNull(library)); - FTL_DCHECK(Dart_IsString(url)); - if (tag == Dart_kCanonicalizeUrl) { - return DartState::Current()->library_loader().CanonicalizeURL(library, url); - } - if (tag == Dart_kImportTag) { - return DartState::Current()->library_loader().Import(library, url); - } - if (tag == Dart_kSourceTag) { - return DartState::Current()->library_loader().Source(library, url); - } - if (tag == Dart_kScriptTag) { - return DartIsolateReloader::HandleLibraryTag(tag, library, url); - } - FTL_NOTREACHED(); - return Dart_NewApiError("Unknown library tag."); -} - -void DartLibraryLoader::WaitForDependencies( - const std::unordered_set& dependencies, - const ftl::Closure& callback) { - if (dependencies.empty()) - return callback(); - dependency_watchers_.insert(std::unique_ptr( - new DependencyWatcher(dependencies, callback))); -} - -void DartLibraryLoader::LoadLibrary(const std::string& name) { - const auto& result = pending_libraries_.insert(std::make_pair(name, nullptr)); - if (result.second) { - // New entry. - std::unique_ptr job = - std::unique_ptr(new ImportJob(this, name, false)); - result.first->second = job.get(); - jobs_.insert(std::move(job)); - } - if (dependency_catcher_) - dependency_catcher_->AddDependency(result.first->second); -} - -void DartLibraryLoader::LoadScript(const std::string& name) { - const auto& result = pending_libraries_.insert(std::make_pair(name, nullptr)); - if (result.second) { - // New entry. - std::unique_ptr job = - std::unique_ptr(new ImportJob(this, name, true)); - result.first->second = job.get(); - jobs_.insert(std::move(job)); - } - if (dependency_catcher_) - dependency_catcher_->AddDependency(result.first->second); -} - -Dart_Handle DartLibraryLoader::Import(Dart_Handle library, Dart_Handle url) { - LoadLibrary(StdStringFromDart(url)); - return Dart_True(); -} - -Dart_Handle DartLibraryLoader::Source(Dart_Handle library, Dart_Handle url) { - std::unique_ptr job = std::unique_ptr( - new SourceJob(this, StdStringFromDart(url), library)); - if (dependency_catcher_) - dependency_catcher_->AddDependency(job.get()); - jobs_.insert(std::move(job)); - return Dart_True(); -} - -Dart_Handle DartLibraryLoader::CanonicalizeURL(Dart_Handle library, - Dart_Handle url) { - return library_provider_->CanonicalizeURL(library, url); -} - -void DartLibraryLoader::DidCompleteImportJob(ImportJob* job, - std::vector buffer) { - tonic::DartIsolateScope scope(dart_state_->isolate()); - tonic::DartApiScope api_scope; - - WatcherSignaler watcher_signaler(*this, job); - - Dart_Handle result; - Dart_Handle source = Dart_NewStringFromUTF8( - reinterpret_cast(buffer.data()), buffer.size()); - - if (job->should_load_as_script()) { - result = Dart_LoadScript(ToDart(job->name()), ToDart(job->resolved_url()), - source, 0, 0); - } else { - result = Dart_LoadLibrary(ToDart(job->name()), ToDart(job->resolved_url()), - source, 0, 0); - } - if (Dart_IsError(result)) { - FTL_LOG(ERROR) << "Error Loading " << job->name() << " " - << Dart_GetError(result); - } - - pending_libraries_.erase(job->name()); - EraseUniquePtr(jobs_, job); -} - -void DartLibraryLoader::DidCompleteSourceJob(SourceJob* job, - std::vector buffer) { - tonic::DartIsolateScope scope(dart_state_->isolate()); - tonic::DartApiScope api_scope; - - WatcherSignaler watcher_signaler(*this, job); - - Dart_Handle source = Dart_NewStringFromUTF8( - reinterpret_cast(buffer.data()), buffer.size()); - Dart_Handle result = Dart_LoadSource( - Dart_HandleFromPersistent(job->library()), ToDart(job->name()), - ToDart(job->resolved_url()), source, 0, 0); - - if (Dart_IsError(result)) { - FTL_LOG(ERROR) << "Error Loading " << job->name() << " " - << Dart_GetError(result); - } - - EraseUniquePtr(jobs_, job); -} - -void DartLibraryLoader::DidFailJob(Job* job) { - tonic::DartIsolateScope scope(dart_state_->isolate()); - tonic::DartApiScope api_scope; - - WatcherSignaler watcher_signaler(*this, job); - - FTL_LOG(ERROR) << "Library Load failed: " << job->name(); - // TODO(eseidel): Call Dart_LibraryHandleError in the SourceJob case? - - EraseUniquePtr(jobs_, job); -} - -} // namespace blink diff --git a/tonic/dart_library_loader.h b/tonic/dart_library_loader.h deleted file mode 100644 index 346da4b57f0..00000000000 --- a/tonic/dart_library_loader.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_TONIC_DART_LIBRARY_LOADER_H_ -#define FLUTTER_TONIC_DART_LIBRARY_LOADER_H_ - -#include -#include -#include -#include -#include - -#include "dart/runtime/include/dart_api.h" -#include "lib/ftl/functional/closure.h" -#include "lib/ftl/logging.h" -#include "lib/ftl/macros.h" - -namespace blink { -class DartDependency; -class DartDependencyCatcher; -class DartLibraryProvider; -class DartState; - -// TODO(abarth): This class seems more complicated than it needs to be. Is -// there some way of simplifying this system? For example, we have a bunch -// of inner classes that could potentially be factored out in some other way. -class DartLibraryLoader { - public: - explicit DartLibraryLoader(DartState* dart_state); - ~DartLibraryLoader(); - - // TODO(dart): This can be called both on the main thread from application - // isolates or from the handle watcher isolate thread. - static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, - Dart_Handle library, - Dart_Handle url); - - void LoadLibrary(const std::string& name); - void LoadScript(const std::string& name); - - void WaitForDependencies( - const std::unordered_set& dependencies, - const ftl::Closure& callback); - - void set_dependency_catcher(DartDependencyCatcher* dependency_catcher) { - FTL_DCHECK(!dependency_catcher_ || !dependency_catcher); - dependency_catcher_ = dependency_catcher; - } - - DartState* dart_state() const { return dart_state_; } - - DartLibraryProvider* library_provider() const { return library_provider_; } - - // The |DartLibraryProvider| must outlive the |DartLibraryLoader|. - void set_library_provider(DartLibraryProvider* library_provider) { - library_provider_ = library_provider; - } - - private: - class Job; - class ImportJob; - class SourceJob; - class DependencyWatcher; - class WatcherSignaler; - - Dart_Handle Import(Dart_Handle library, Dart_Handle url); - Dart_Handle Source(Dart_Handle library, Dart_Handle url); - Dart_Handle CanonicalizeURL(Dart_Handle library, Dart_Handle url); - void DidCompleteImportJob(ImportJob* job, std::vector buffer); - void DidCompleteSourceJob(SourceJob* job, std::vector buffer); - void DidFailJob(Job* job); - - DartState* dart_state_; - DartLibraryProvider* library_provider_; - std::unordered_map pending_libraries_; - std::unordered_set> jobs_; - std::unordered_set> dependency_watchers_; - DartDependencyCatcher* dependency_catcher_; - - FTL_DISALLOW_COPY_AND_ASSIGN(DartLibraryLoader); -}; - -} // namespace blink - -#endif // FLUTTER_TONIC_DART_LIBRARY_LOADER_H_ diff --git a/tonic/dart_library_provider.cc b/tonic/dart_library_provider.cc deleted file mode 100644 index 3495170dd82..00000000000 --- a/tonic/dart_library_provider.cc +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/tonic/dart_library_provider.h" - -namespace blink { - -DartLibraryProvider::~DartLibraryProvider() { -} - -} // namespace blink diff --git a/tonic/dart_library_provider.h b/tonic/dart_library_provider.h deleted file mode 100644 index 57b397bdec4..00000000000 --- a/tonic/dart_library_provider.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_TONIC_DART_LIBRARY_PROVIDER_H_ -#define FLUTTER_TONIC_DART_LIBRARY_PROVIDER_H_ - -#include -#include - -#include "dart/runtime/include/dart_api.h" -#include "mojo/public/cpp/system/data_pipe.h" - -namespace blink { - -struct DartLibraryStream { - mojo::ScopedDataPipeConsumerHandle handle; - std::string resolved_url; -}; - -class DartLibraryProvider { - public: - virtual DartLibraryStream GetLibraryAsStream(const std::string& name) = 0; - - virtual Dart_Handle CanonicalizeURL(Dart_Handle library, Dart_Handle url) = 0; - - virtual ~DartLibraryProvider(); -}; - -} // namespace blink - -#endif // FLUTTER_TONIC_DART_LIBRARY_PROVIDER_H_ diff --git a/tonic/dart_library_provider_files.cc b/tonic/dart_library_provider_files.cc deleted file mode 100644 index a8cd455b971..00000000000 --- a/tonic/dart_library_provider_files.cc +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/tonic/dart_library_provider_files.h" - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/strings/string_util.h" -#include "base/threading/worker_pool.h" -#include "lib/tonic/converter/dart_converter.h" -#include "mojo/data_pipe_utils/data_pipe_utils.h" - -namespace sky { -namespace shell { -namespace { - -void CopyComplete(base::FilePath file, std::string uri, bool success) { - if (!success) - LOG(FATAL) << "Failed to load " << file.AsUTF8Unsafe() << " (" << uri - << ")"; -} - -// Extract the scheme prefix ('package:' or 'file:' from ) -static std::string ExtractSchemePrefix(std::string url) { - if (base::StartsWithASCII(url, "package:", true)) { - return "package:"; - } else if (base::StartsWithASCII(url, "file:", true)) { - return "file:"; - } - return ""; -} - -// Extract the path from a package: or file: url. -static std::string ExtractPath(std::string url) { - if (base::StartsWithASCII(url, "package:", true)) { - base::ReplaceFirstSubstringAfterOffset(&url, 0, "package:", ""); - } else if (base::StartsWithASCII(url, "file:", true)) { - base::ReplaceFirstSubstringAfterOffset(&url, 0, "file:", ""); - } - return url; -} - -base::FilePath SimplifyPath(const base::FilePath& path) { - std::vector components; - path.GetComponents(&components); - auto it = components.begin(); - base::FilePath result(*it++); - for (; it != components.end(); it++) { - auto& component = *it; - if (component == base::FilePath::kCurrentDirectory) - continue; - if (component == base::FilePath::kParentDirectory) - result = result.DirName(); - else - result = result.Append(component); - } - return result; -} - -} // namespace - -DartLibraryProviderFiles::DartLibraryProviderFiles() {} - -DartLibraryProviderFiles::~DartLibraryProviderFiles() {} - -void DartLibraryProviderFiles::LoadPackagesMap(const std::string& packages) { - packages_ = base::FilePath(packages); - std::string packages_source; - if (!base::ReadFileToString(base::MakeAbsoluteFilePath(packages_), - &packages_source)) { - LOG(ERROR) << "error: Unable to load .packages file '" - << packages_.AsUTF8Unsafe() << "'."; - exit(1); - } - std::string error; - if (!packages_map_.Parse(packages_source, &error)) { - LOG(ERROR) << "error: Unable to parse .packages file '" - << packages_.AsUTF8Unsafe() << "'.\n" - << error; - exit(1); - } -} - -blink::DartLibraryStream DartLibraryProviderFiles::GetLibraryAsStream( - const std::string& name) { - mojo::DataPipe pipe; - base::FilePath path = GetFilePathForURL(name); - base::FilePath source = base::MakeAbsoluteFilePath(path); - blink::DartLibraryStream result; - result.handle = std::move(pipe.consumer_handle); - result.resolved_url = "file://" + source.value(); - scoped_refptr runner = - base::WorkerPool::GetTaskRunner(true); - mojo::common::CopyFromFile(source, pipe.producer_handle.Pass(), 0, - runner.get(), - base::Bind(&CopyComplete, source, name)); - return result; -} - -Dart_Handle DartLibraryProviderFiles::CanonicalizeURL(Dart_Handle library, - Dart_Handle url) { - std::string string = tonic::StdStringFromDart(url); - if (base::StartsWithASCII(string, "dart:", true)) - return url; - if (base::StartsWithASCII(string, "package:", true)) - return url; - if (base::StartsWithASCII(string, "file:", true)) { - base::ReplaceFirstSubstringAfterOffset(&string, 0, "file:", ""); - return tonic::StdStringToDart(string); - ; - } - - std::string library_url = tonic::StdStringFromDart(Dart_LibraryUrl(library)); - std::string prefix = ExtractSchemePrefix(library_url); - std::string path = ExtractPath(library_url); - base::FilePath base_path(path); - base::FilePath resolved_path = base_path.DirName().Append(string); - base::FilePath normalized_path = SimplifyPath(resolved_path); - return tonic::StdStringToDart(prefix + normalized_path.AsUTF8Unsafe()); -} - -base::FilePath DartLibraryProviderFiles::GetFilePathForURL(std::string url) { - if (base::StartsWithASCII(url, "package:", true)) - return GetFilePathForPackageURL(url); - if (base::StartsWithASCII(url, "file:", true)) - return GetFilePathForFileURL(url); - - return base::FilePath(url); -} - -base::FilePath DartLibraryProviderFiles::GetFilePathForPackageURL( - std::string url) { - DCHECK(base::StartsWithASCII(url, "package:", true)); - base::ReplaceFirstSubstringAfterOffset(&url, 0, "package:", ""); - size_t slash = url.find('/'); - if (slash == std::string::npos) - return base::FilePath(); - std::string package = url.substr(0, slash); - std::string library_path = url.substr(slash + 1); - std::string package_path = packages_map_.Resolve(package); - if (package_path.empty()) - return base::FilePath(); - if (base::StartsWithASCII(package_path, "file://", true)) { - base::ReplaceFirstSubstringAfterOffset(&package_path, 0, "file://", ""); - return base::FilePath(package_path + library_path); - } - return packages_.DirName().Append(package_path).Append(library_path); -} - -base::FilePath DartLibraryProviderFiles::GetFilePathForFileURL( - std::string url) { - DCHECK(base::StartsWithASCII(url, "file://", true)); - base::ReplaceFirstSubstringAfterOffset(&url, 0, "file://", ""); - return base::FilePath(url); -} - -} // namespace shell -} // namespace sky diff --git a/tonic/dart_library_provider_files.h b/tonic/dart_library_provider_files.h deleted file mode 100644 index 7746c5b60c2..00000000000 --- a/tonic/dart_library_provider_files.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef SKY_SHELL_DART_DART_LIBRARY_PROVIDER_FILES_H_ -#define SKY_SHELL_DART_DART_LIBRARY_PROVIDER_FILES_H_ - -#include "base/files/file_path.h" -#include "flutter/tonic/dart_library_provider.h" -#include "lib/ftl/macros.h" -#include "lib/tonic/parsers/packages_map.h" - -namespace sky { -namespace shell { - -class DartLibraryProviderFiles : public blink::DartLibraryProvider { - public: - DartLibraryProviderFiles(); - ~DartLibraryProviderFiles() override; - - void LoadPackagesMap(const std::string& packages); - - protected: - // |DartLibraryProvider| implementation: - blink::DartLibraryStream GetLibraryAsStream(const std::string& name) override; - Dart_Handle CanonicalizeURL(Dart_Handle library, Dart_Handle url) override; - - private: - base::FilePath GetFilePathForURL(std::string url); - base::FilePath GetFilePathForPackageURL(std::string url); - base::FilePath GetFilePathForFileURL(std::string url); - - base::FilePath packages_; - tonic::PackagesMap packages_map_; - - FTL_DISALLOW_COPY_AND_ASSIGN(DartLibraryProviderFiles); -}; - -} // namespace shell -} // namespace sky - -#endif // SKY_SHELL_DART_DART_LIBRARY_PROVIDER_FILES_H_ diff --git a/tonic/dart_snapshot_loader.cc b/tonic/dart_snapshot_loader.cc deleted file mode 100644 index c6546df4d13..00000000000 --- a/tonic/dart_snapshot_loader.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/tonic/dart_snapshot_loader.h" - -#include - -#include "flutter/tonic/dart_state.h" -#include "flutter/glue/trace_event.h" -#include "lib/tonic/converter/dart_converter.h" -#include "lib/tonic/logging/dart_error.h" -#include "lib/tonic/scopes/dart_api_scope.h" -#include "lib/tonic/scopes/dart_isolate_scope.h" - -using tonic::LogIfError; - -namespace blink { - -DartSnapshotLoader::DartSnapshotLoader(tonic::DartState* dart_state) - : dart_state_(dart_state->GetWeakPtr()) {} - -DartSnapshotLoader::~DartSnapshotLoader() {} - -void DartSnapshotLoader::LoadSnapshot(mojo::ScopedDataPipeConsumerHandle pipe, - const ftl::Closure& callback) { - TRACE_EVENT_ASYNC_BEGIN0("flutter", "DartSnapshotLoader::LoadSnapshot", this); - - drainer_.reset(new glue::DrainDataPipeJob( - std::move(pipe), [this, callback](std::vector buffer) { - TRACE_EVENT_ASYNC_END0("flutter", "DartSnapshotLoader::LoadSnapshot", - this); - // TODO(abarth): Should we check dart_state_ for null? - { - tonic::DartIsolateScope scope(dart_state_->isolate()); - tonic::DartApiScope api_scope; - - LogIfError(Dart_LoadScriptFromSnapshot( - reinterpret_cast(buffer.data()), buffer.size())); - } - - callback(); - })); -} - -} // namespace blink diff --git a/tonic/dart_snapshot_loader.h b/tonic/dart_snapshot_loader.h deleted file mode 100644 index 237186c3f10..00000000000 --- a/tonic/dart_snapshot_loader.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_TONIC_DART_SNAPSHOT_LOADER_H_ -#define FLUTTER_TONIC_DART_SNAPSHOT_LOADER_H_ - -#include - -#include "dart/runtime/include/dart_api.h" -#include "flutter/glue/drain_data_pipe_job.h" -#include "lib/ftl/functional/closure.h" -#include "lib/ftl/macros.h" -#include "lib/tonic/dart_state.h" - -namespace blink { - -class DartSnapshotLoader { - public: - explicit DartSnapshotLoader(tonic::DartState* dart_state); - ~DartSnapshotLoader(); - - void LoadSnapshot(mojo::ScopedDataPipeConsumerHandle pipe, - const ftl::Closure& callback); - - private: - ftl::WeakPtr dart_state_; - std::unique_ptr drainer_; - - FTL_DISALLOW_COPY_AND_ASSIGN(DartSnapshotLoader); -}; - -} // namespace blink - -#endif // FLUTTER_TONIC_DART_SNAPSHOT_LOADER_H_ diff --git a/tonic/dart_state.cc b/tonic/dart_state.cc index c0a85d5a514..08a12698627 100644 --- a/tonic/dart_state.cc +++ b/tonic/dart_state.cc @@ -4,13 +4,9 @@ #include "flutter/tonic/dart_state.h" -#include "lib/tonic/converter/dart_converter.h" -#include "flutter/tonic/dart_library_loader.h" - namespace blink { -DartState::DartState() - : library_loader_(new DartLibraryLoader(this)) {} +DartState::DartState() {} DartState::~DartState() {} diff --git a/tonic/dart_state.h b/tonic/dart_state.h index 37724a0de20..c393e4e1125 100644 --- a/tonic/dart_state.h +++ b/tonic/dart_state.h @@ -6,21 +6,13 @@ #define FLUTTER_TONIC_DART_STATE_H_ #include "dart/runtime/include/dart_api.h" -#include "flutter/tonic/dart_isolate_reloader.h" #include "lib/tonic/dart_persistent_value.h" #include "lib/tonic/dart_state.h" #include "lib/tonic/scopes/dart_api_scope.h" #include "lib/tonic/scopes/dart_isolate_scope.h" namespace blink { -class DartExceptionFactory; -class DartLibraryLoader; -// DartState represents the state associated with a given Dart isolate. The -// lifetime of this object is controlled by the DartVM. If you want to hold a -// reference to a DartState instance, please hold a base::WeakPtr. -// -// DartState is analogous to gin::PerIsolateData and JSC::ExecState. class DartState : public tonic::DartState { public: DartState(); @@ -29,19 +21,6 @@ class DartState : public tonic::DartState { static DartState* From(Dart_Isolate isolate); static DartState* Current(); - DartLibraryLoader& library_loader() { return *library_loader_; } - - // Takes ownership of |isolate_reloader|. - void set_isolate_reloader( - std::unique_ptr isolate_reloader) { - isolate_reloader_ = std::move(isolate_reloader); - } - DartIsolateReloader* isolate_reloader() { return isolate_reloader_.get(); } - - private: - std::unique_ptr library_loader_; - std::unique_ptr isolate_reloader_; - protected: FTL_DISALLOW_COPY_AND_ASSIGN(DartState); };