diff --git a/engine/core/core.gni b/engine/core/core.gni index 85e6052628b..65f2df0acda 100644 --- a/engine/core/core.gni +++ b/engine/core/core.gni @@ -1058,6 +1058,8 @@ sky_core_files = [ "script/dart_loader.h", "script/dart_service_isolate.cc", "script/dart_service_isolate.h", + "script/dart_snapshot_loader.cc", + "script/dart_snapshot_loader.h", "script/dom_dart_state.cc", "script/dom_dart_state.h", "script/monitor.h", diff --git a/engine/core/script/dart_controller.cc b/engine/core/script/dart_controller.cc index 80338ba8a09..d84cb4ede74 100644 --- a/engine/core/script/dart_controller.cc +++ b/engine/core/script/dart_controller.cc @@ -27,6 +27,7 @@ #include "sky/engine/core/script/dart_dependency_catcher.h" #include "sky/engine/core/script/dart_loader.h" #include "sky/engine/core/script/dart_service_isolate.h" +#include "sky/engine/core/script/dart_snapshot_loader.h" #include "sky/engine/core/script/dom_dart_state.h" #include "sky/engine/public/platform/Platform.h" #include "sky/engine/tonic/dart_api_scope.h" @@ -40,6 +41,16 @@ #include "sky/engine/wtf/text/TextPosition.h" namespace blink { +namespace { + +void CreateEmptyRootLibraryIfNeeded() { + if (Dart_IsNull(Dart_RootLibrary())) { + Dart_LoadScript(Dart_NewStringFromCString("dart:empty"), Dart_EmptyString(), + 0, 0); + } +} + +} // namespace #if ENABLE(DART_STRICT) static const char* kCheckedModeArgs[] = {"--enable_asserts", @@ -126,6 +137,9 @@ void DartController::DidLoadMainLibrary(KURL url) { } void DartController::LoadMainLibrary(const KURL& url, mojo::URLResponsePtr response) { + DartState::Scope scope(dart_state()); + CreateEmptyRootLibraryIfNeeded(); + DartLoader& loader = dart_state()->loader(); DartDependencyCatcher dependency_catcher(loader); loader.LoadLibrary(url, response.Pass()); @@ -133,13 +147,33 @@ void DartController::LoadMainLibrary(const KURL& url, mojo::URLResponsePtr respo base::Bind(&DartController::DidLoadMainLibrary, weak_factory_.GetWeakPtr(), url)); } +void DartController::DidLoadSnapshot() { + DCHECK(Dart_CurrentIsolate() == nullptr); + snapshot_loader_ = nullptr; + + Dart_Isolate isolate = dart_state()->isolate(); + DartIsolateScope isolate_scope(isolate); + DartApiScope dart_api_scope; + + Dart_Handle library = Dart_RootLibrary(); + if (LogIfError(library)) + return; + DartInvokeAppField(library, ToDart("main"), 0, nullptr); +} + +void DartController::LoadSnapshot(const KURL& url, mojo::URLResponsePtr response) { + snapshot_loader_ = adoptPtr(new DartSnapshotLoader(dart_state())); + snapshot_loader_->LoadSnapshot(url, response.Pass(), + base::Bind(&DartController::DidLoadSnapshot, weak_factory_.GetWeakPtr())); +} + void DartController::LoadScriptInModule( AbstractModule* module, const String& source, const TextPosition& position, const LoadFinishedCallback& finished_callback) { - DartIsolateScope isolate_scope(dart_state()->isolate()); - DartApiScope dart_api_scope; + DartState::Scope scope(dart_state()); + CreateEmptyRootLibraryIfNeeded(); DartDependencyCatcher dependency_catcher(dart_state()->loader()); Dart_Handle library_handle = CreateLibrary(module, source, position); @@ -274,6 +308,7 @@ static Dart_Isolate IsolateCreateCallback(const char* script_uri, // Create & start the handle watcher isolate CHECK(kDartIsolateSnapshotBuffer); + // TODO(abarth): Who deletes this DartState instance? DartState* dart_state = new DartState(); Dart_Isolate isolate = Dart_CreateIsolate("sky:handle_watcher", "", kDartIsolateSnapshotBuffer, @@ -289,9 +324,8 @@ static Dart_Isolate IsolateCreateCallback(const char* script_uri, Builtin::SetNativeResolver(Builtin::kMojoInternalLibrary); Builtin::SetNativeResolver(Builtin::kIOLibrary); - // Ensure the isolate has a root library. - Dart_LoadScript(Dart_NewStringFromCString("dart:empty"), - Dart_NewStringFromCString(""), 0, 0); + if (!script_uri) + CreateEmptyRootLibraryIfNeeded(); } Dart_ExitIsolate(); @@ -334,10 +368,6 @@ void DartController::CreateIsolateFor(PassOwnPtr state) { { DartApiScope apiScope; - // Ensure the isolate has a root library. - Dart_LoadScript(Dart_NewStringFromCString("dart:empty"), - Dart_NewStringFromCString(""), 0, 0); - Builtin::SetNativeResolver(Builtin::kBuiltinLibrary); Builtin::SetNativeResolver(Builtin::kMojoInternalLibrary); Builtin::SetNativeResolver(Builtin::kIOLibrary); diff --git a/engine/core/script/dart_controller.h b/engine/core/script/dart_controller.h index af2de5feca3..8834b84792c 100644 --- a/engine/core/script/dart_controller.h +++ b/engine/core/script/dart_controller.h @@ -18,6 +18,7 @@ namespace blink { class AbstractModule; class BuiltinSky; class DOMDartState; +class DartSnapshotLoader; class DartValue; class HTMLScriptElement; class KURL; @@ -35,6 +36,7 @@ class DartController { // Can either issue the url load ourselves or take an existing response: void LoadMainLibrary(const KURL& url, mojo::URLResponsePtr response = nullptr); + void LoadSnapshot(const KURL& url, mojo::URLResponsePtr response = nullptr); void LoadScriptInModule(AbstractModule* module, const String& source, @@ -57,9 +59,11 @@ class DartController { const TextPosition& position); void DidLoadMainLibrary(KURL url); + void DidLoadSnapshot(); OwnPtr dom_dart_state_; OwnPtr builtin_sky_; + OwnPtr snapshot_loader_; base::WeakPtrFactory weak_factory_; diff --git a/engine/core/script/dart_snapshot_loader.cc b/engine/core/script/dart_snapshot_loader.cc new file mode 100644 index 00000000000..fc296b33dd1 --- /dev/null +++ b/engine/core/script/dart_snapshot_loader.cc @@ -0,0 +1,66 @@ +// 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 "sky/engine/config.h" +#include "sky/engine/core/script/dart_snapshot_loader.h" + +#include "base/callback.h" +#include "base/trace_event/trace_event.h" +#include "sky/engine/platform/weborigin/KURL.h" +#include "sky/engine/tonic/dart_api_scope.h" +#include "sky/engine/tonic/dart_converter.h" +#include "sky/engine/tonic/dart_error.h" +#include "sky/engine/tonic/dart_isolate_scope.h" +#include "sky/engine/wtf/MainThread.h" + +using mojo::common::DataPipeDrainer; + +namespace blink { + +DartSnapshotLoader::DartSnapshotLoader(DartState* dart_state) + : dart_state_(dart_state->GetWeakPtr()) { +} + +DartSnapshotLoader::~DartSnapshotLoader() { +} + +void DartSnapshotLoader::LoadSnapshot(const KURL& url, + mojo::URLResponsePtr response, + const base::Closure& callback) { + TRACE_EVENT_ASYNC_BEGIN0("sky", "DartSnapshotLoader::LoadSnapshot", this); + callback_ = callback; + + if (!response) { + fetcher_ = adoptPtr(new MojoFetcher(this, url)); + } else { + OnReceivedResponse(response.Pass()); + } +} + +void DartSnapshotLoader::OnReceivedResponse(mojo::URLResponsePtr response) { + if (response->status_code != 200) { + callback_.Run(); + return; + } + drainer_ = adoptPtr(new DataPipeDrainer(this, response->body.Pass())); +} + +void DartSnapshotLoader::OnDataAvailable(const void* data, size_t num_bytes) { + buffer_.append(static_cast(data), num_bytes); +} + +void DartSnapshotLoader::OnDataComplete() { + TRACE_EVENT_ASYNC_END0("sky", "DartSnapshotLoader::LoadSnapshot", this); + + { + DartIsolateScope scope(dart_state_->isolate()); + DartApiScope api_scope; + + LogIfError(Dart_LoadScriptFromSnapshot(buffer_.data(), buffer_.size())); + } + + callback_.Run(); +} + +} // namespace blink diff --git a/engine/core/script/dart_snapshot_loader.h b/engine/core/script/dart_snapshot_loader.h new file mode 100644 index 00000000000..43930069d3e --- /dev/null +++ b/engine/core/script/dart_snapshot_loader.h @@ -0,0 +1,55 @@ +// 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_ENGINE_CORE_SCRIPT_DART_SNAPSHOT_LOADER_H_ +#define SKY_ENGINE_CORE_SCRIPT_DART_SNAPSHOT_LOADER_H_ + +#include "base/callback_forward.h" +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "dart/runtime/include/dart_api.h" +#include "mojo/common/data_pipe_drainer.h" +#include "mojo/services/network/public/interfaces/url_loader.mojom.h" +#include "sky/engine/platform/fetcher/MojoFetcher.h" +#include "sky/engine/wtf/OwnPtr.h" +#include "sky/engine/wtf/Vector.h" +#include "sky/engine/wtf/text/WTFString.h" + +namespace blink { + +class DartState; +class KURL; + +class DartSnapshotLoader : public MojoFetcher::Client, + public mojo::common::DataPipeDrainer::Client { + public: + explicit DartSnapshotLoader(DartState* dart_state); + ~DartSnapshotLoader(); + + void LoadSnapshot(const KURL& url, mojo::URLResponsePtr response, + const base::Closure& callback); + + DartState* dart_state() const { return dart_state_.get(); } + + private: + // MojoFetcher::Client + void OnReceivedResponse(mojo::URLResponsePtr response) override; + + // mojo::common::DataPipeDrainer::Client + void OnDataAvailable(const void* data, size_t num_bytes) override; + void OnDataComplete() override; + + base::WeakPtr dart_state_; + // TODO(abarth): Should we be using SharedBuffer to buffer the data? + Vector buffer_; + OwnPtr fetcher_; + OwnPtr drainer_; + base::Closure callback_; + + DISALLOW_COPY_AND_ASSIGN(DartSnapshotLoader); +}; + +} // namespace blink + +#endif // SKY_ENGINE_CORE_SCRIPT_DART_SNAPSHOT_LOADER_H_ diff --git a/engine/public/sky/sky_view.cc b/engine/public/sky/sky_view.cc index d16243f6e7d..a282fa00614 100644 --- a/engine/public/sky/sky_view.cc +++ b/engine/public/sky/sky_view.cc @@ -47,7 +47,9 @@ void SkyView::SetDisplayMetrics(const SkyDisplayMetrics& metrics) { data_->view_->setDisplayMetrics(display_metrics_); } -void SkyView::Load(const WebURL& url, mojo::URLResponsePtr response) { +void SkyView::Load(const WebURL& web_url, mojo::URLResponsePtr response) { + KURL url = web_url; + data_->view_ = View::create(base::Bind( &SkyView::ScheduleFrame, weak_factory_.GetWeakPtr())); data_->view_->setDisplayMetrics(display_metrics_); @@ -63,7 +65,10 @@ void SkyView::Load(const WebURL& url, mojo::URLResponsePtr response) { client_->DidCreateIsolate(isolate); } - dart_controller_->LoadMainLibrary(url, response.Pass()); + if (url.path().endsWith(".snapshot")) + dart_controller_->LoadSnapshot(url, response.Pass()); + else + dart_controller_->LoadMainLibrary(url, response.Pass()); } void SkyView::BeginFrame(base::TimeTicks frame_time) { diff --git a/engine/web/WebViewImpl.cpp b/engine/web/WebViewImpl.cpp index 10ae28b364b..6b53e0b56a2 100644 --- a/engine/web/WebViewImpl.cpp +++ b/engine/web/WebViewImpl.cpp @@ -104,7 +104,8 @@ bool WebView::shouldUseWebView(const GURL& url) filename.resize(queryStart); // For now .dart indicates we should use SkyView. Eventually we'll // use SkyView for all urls regardless of file extension. - return !EndsWith(filename, ".dart", false); + return !EndsWith(filename, ".dart", false) + && !EndsWith(filename, ".snapshot", false); } WebView* WebView::create(WebViewClient* client) diff --git a/tools/packager/loader.cc b/tools/packager/loader.cc index 3d82739483d..489359da7ea 100644 --- a/tools/packager/loader.cc +++ b/tools/packager/loader.cc @@ -15,9 +15,6 @@ namespace { -static const char kSkyInternalsLibraryName[] = "dart:sky.internals"; -static const char kSkyInternalsURL[] = "package:sky/internals.dart"; - std::string Fetch(const std::string& url) { base::FilePath path(url); std::string source; @@ -122,14 +119,6 @@ Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, return Dart_NewApiError("Unknown library tag."); } -void LoadSkyInternals() { - DartApiScope api_scope; - - Dart_Handle library_name = StringToDart(kSkyInternalsLibraryName); - std::string url = GetLoader().CanonicalizePackageURL(kSkyInternalsURL); - LogIfError(Dart_LoadLibrary(library_name, StringToDart(Fetch(url)), 0, 0)); -} - void LoadScript(const std::string& url) { LogIfError( Dart_LoadScript(StringToDart(url), StringToDart(Fetch(url)), 0, 0)); diff --git a/tools/packager/loader.h b/tools/packager/loader.h index 31385032423..da9b67a4e3c 100644 --- a/tools/packager/loader.h +++ b/tools/packager/loader.h @@ -12,7 +12,6 @@ Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle url); -void LoadSkyInternals(); void LoadScript(const std::string& url); #endif // SKY_TOOLS_PACKAGER_LOADER_H_ diff --git a/tools/packager/vm.cc b/tools/packager/vm.cc index a36a70fe579..71761e89c5c 100644 --- a/tools/packager/vm.cc +++ b/tools/packager/vm.cc @@ -32,7 +32,6 @@ Dart_Isolate CreateDartIsolate() { CHECK(isolate) << error; CHECK(!LogIfError(Dart_SetLibraryTagHandler(HandleLibraryTag))); - LoadSkyInternals(); Dart_ExitIsolate(); return isolate;