Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(184)

Unified Diff: Source/bindings/dart/DartAsyncLoader.cpp

Issue 26490003: Reapply "Move isolate loading to a separate loader isolate." (Closed) Base URL: svn://svn.chromium.org/multivm/trunk/webkit
Patch Set: Initialize flag properly Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/bindings/dart/DartAsyncLoader.h ('k') | Source/bindings/dart/DartController.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/bindings/dart/DartAsyncLoader.cpp
diff --git a/Source/bindings/dart/DartAsyncLoader.cpp b/Source/bindings/dart/DartAsyncLoader.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f9affeb6bdb2149fe8e2136e598368f356d64f95
--- /dev/null
+++ b/Source/bindings/dart/DartAsyncLoader.cpp
@@ -0,0 +1,263 @@
+// Copyright (c) 2013, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "config.h"
+#include "bindings/dart/DartAsyncLoader.h"
+
+#include "FetchInitiatorTypeNames.h"
+#include "bindings/dart/DartUtilities.h"
+#include "bindings/v8/ScriptSourceCode.h"
+#include "core/dom/Document.h"
+#include "core/dom/ScriptLoader.h"
+#include "core/fetch/FetchRequest.h"
+#include "core/fetch/ResourceClient.h"
+#include "core/fetch/ResourceFetcher.h"
+#include "core/fetch/ScriptResource.h"
+#include "core/inspector/ScriptCallStack.h"
+
+#include <dart_api.h>
+
+namespace WebCore {
+
+static const unsigned dartTypeID = 0xDAADDAAD;
+
+void DartAsyncLoader::LoadCallback::reportError(const String& error, const String& url)
+{
+ m_originDocument->logExceptionToConsole(error + ": " + url, url, 0, 0, 0);
+ if (m_scriptLoader)
+ m_scriptLoader->dispatchErrorEvent();
+}
+
+ResourcePtr<ScriptResource> DartAsyncLoader::LoadCallback::requestScript(FetchRequest& request)
+{
+ return m_originDocument->fetcher()->requestScript(request);
+}
+
+
+DartAsyncLoader::DartAsyncLoader(const String& url, PassRefPtr<DartAsyncLoader::LoadCallback> loadCallback)
+ : m_loadCallback(loadCallback)
+ , m_mainScriptFetched(false)
+{
+ Document* document = m_loadCallback->document();
+ char* error;
+
+ const KURL canonical = KURL(document->baseURL(), url);
+ m_topUrl = canonical.string();
+
+ DartDOMData* domData = new DartDOMData(document, false);
+ domData->setAsyncLoader(adoptRef(this));
+
+ const uint8_t* snapshot = DartUtilities::fullSnapshot(document->frame());
+ m_parseIsolate = Dart_CreateIsolate("dartium.fetch", "", snapshot, domData, &error);
+ if (!m_parseIsolate)
+ m_loadCallback->reportError(error, url);
+
+ Dart_Handle result = Dart_SetLibraryTagHandler(&libraryTagHandlerCallback);
+ ASSERT(!Dart_IsError(result));
+ UNUSED_PARAM(result);
+
+ m_pendingLibraries.add(m_topUrl);
+}
+
+DartAsyncLoader::~DartAsyncLoader()
+{
+ m_loadCallback = 0;
+}
+
+void DartAsyncLoader::findDependences(const String& url, const String& source, intptr_t lineNumber)
+{
+ ASSERT(m_pendingLibraries.contains(url) || m_pendingSource.contains(url));
+
+ DartIsolateScope isolateScope(m_parseIsolate);
+ DartApiScope dartApiScope;
+
+ if (!m_mainScriptFetched) {
+ ASSERT(m_topUrl == url);
+ m_topSource = source;
+ m_lineNumber = lineNumber;
+ m_mainScriptFetched = true;
+ }
+
+ if (m_pendingLibraries.contains(url)) {
+ processLibrary(url, source);
+ m_pendingLibraries.remove(url);
+ } else {
+ ASSERT(m_pendingSource.contains(url));
+ // No imports or parts, so no need to process further.
+ m_pendingSource.remove(url);
+ }
+}
+
+void DartAsyncLoader::reportError(Dart_Handle error, const String& url)
+{
+ reportError(Dart_GetError(error), url);
+}
+
+void DartAsyncLoader::processLibrary(const String& url, const String& source)
+{
+ ASSERT(m_pendingLibraries.contains(url));
+
+ Dart_Handle result = Dart_LoadLibrary(DartUtilities::stringToDartString(url), DartUtilities::convertSourceString(source));
+ if (Dart_IsError(result))
+ reportError(result, url);
+}
+
+void DartAsyncLoader::process(const String& url, const String& source, intptr_t lineNumber)
+{
+ ASSERT(!m_urlSourceMap.contains(url));
+ m_urlSourceMap.add(url, source);
+
+ findDependences(url, source, lineNumber);
+ if (ready()) {
+ // All dependences are in.
+ RefPtr<DartAsyncLoader> guard(this);
+ m_loadCallback->ready(guard);
+
+ // Free this loader and its isolate.
+ Dart_EnterIsolate(m_parseIsolate);
+ DartDOMData::current()->setAsyncLoader(0);
+ Dart_ShutdownIsolate();
+ }
+}
+
+Dart_Handle DartAsyncLoader::libraryTagHandlerCallback(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle urlHandle)
+{
+ ASSERT(Dart_CurrentIsolate());
+ ASSERT(Dart_IsLibrary(library));
+
+ const String url = DartUtilities::toString(urlHandle);
+
+ if (tag == Dart_kCanonicalizeUrl) {
+ // If a dart application calls spawnUri, the DartVM will call this
+ // libraryTagHandler to canonicalize the url.
+ // DartDOMData::current()->scriptLoader() may be 0 at this point.
+ return DartUtilities::canonicalizeUrl(library, urlHandle, url);
+ }
+
+ RefPtr<DartAsyncLoader> loader = DartDOMData::current()->asyncLoader();
+ ASSERT(loader);
+
+ if (!url.startsWith("dart:")) {
+ // Fetch non-system URLs.
+ if (tag == Dart_kImportTag) {
+ loader->m_pendingLibraries.add(url);
+ } else if (tag == Dart_kSourceTag) {
+ loader->m_pendingSource.add(url);
+ } else {
+ ASSERT_NOT_REACHED();
+ }
+ loader->fetchScriptResource(url);
+ }
+ return Dart_NewBoolean(true);
+}
+
+class ScriptLoadedCallback : public ResourceClient {
+public:
+ ScriptLoadedCallback(String url, PassRefPtr<DartAsyncLoader> loader, ResourcePtr<ScriptResource> scriptResource)
+ : m_url(url)
+ , m_loader(loader)
+ , m_scriptResource(scriptResource)
+ {
+ }
+
+ virtual void notifyFinished(Resource* cachedResource)
+ {
+ ASSERT(cachedResource->type() == Resource::Script);
+ ASSERT(cachedResource == m_scriptResource.get());
+ ASSERT(WTF::isMainThread());
+
+ if (cachedResource->errorOccurred()) {
+ m_loader->reportError(String("An error occurred loading file"), m_url);
+ } else if (cachedResource->wasCanceled()) {
+ // FIXME: shall we let VM know, so it can inform application some of its
+ // resources cannot be loaded?
+ m_loader->reportError(String("File request cancelled"), m_url);
+ } else {
+ ScriptSourceCode sourceCode(m_scriptResource.get());
+ // FIXME: Should we check for cached metadata?
+ // CachedMetadata* cachedMetadata = m_scriptResource->cachedMetadata(dartTypeID);
+
+ // Use the original url associated with the Script so that
+ // redirects do not break the DartScriptLoader.
+ // FIXME: is this the correct behavior? This functionality is
+ // very convenient when you want the source file to act as if
+ // it was from the original location but that isn't always
+ // what the user expects.
+ m_loader->process(m_url, sourceCode.source(), 0);
+ }
+
+ m_scriptResource->removeClient(this);
+ delete this;
+ }
+
+private:
+ String m_url;
+ RefPtr<DartAsyncLoader> m_loader;
+ ResourcePtr<ScriptResource> m_scriptResource;
+};
+
+static String resolveUrl(String mainLibraryURL, const String& url)
+{
+ if (!url.startsWith("package:") || url.startsWith("package://"))
+ return url;
+
+ String packageRoot;
+ String packageUrl;
+ if (const char* packageRootOverride = getenv("DART_PACKAGE_ROOT")) {
+ // Resolve with respect to the override. Append a
+ // slash to ensure that resolution is against this
+ // path and not its parent.
+ packageRoot = String(packageRootOverride) + "/";
+ // Strip the 'package:' prefix.
+ packageUrl = url.substring(8);
+ } else {
+ // Resolve with respect to the entry point's URL. Note, the
+ // trailing file name in the entry point URL (e.g.,
+ // 'rootpath/mainapp.dart') is stripped by the KURL
+ // constructor below.
+ packageRoot = mainLibraryURL;
+ packageUrl = String("packages/") + url.substring(8);
+ }
+ return KURL(KURL(KURL(), packageRoot), packageUrl).string();
+}
+
+void DartAsyncLoader::fetchScriptResource(const String& url)
+{
+ // Request loading of script dependencies.
+ FetchRequest request(m_loadCallback->completeURL(resolveUrl(m_topUrl, url)),
+ FetchInitiatorTypeNames::document, "utf8");
+ // FIXME: what about charset for this script, maybe use charset of initial script tag?
+ ResourcePtr<ScriptResource> scriptResource = m_loadCallback->requestScript(request);
+ if (scriptResource)
+ scriptResource->addClient(new ScriptLoadedCallback(m_loadCallback->completeURL(url), this, scriptResource));
+ else
+ m_loadCallback->reportError(String("File request error"), url);
+}
+
+}
« no previous file with comments | « Source/bindings/dart/DartAsyncLoader.h ('k') | Source/bindings/dart/DartController.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698