| Index: Source/bindings/dart/DartApplicationLoader.cpp
|
| diff --git a/Source/bindings/dart/DartApplicationLoader.cpp b/Source/bindings/dart/DartApplicationLoader.cpp
|
| index d1170ca17862fdc471ac56cd0a69b9b50f588d2f..b95a191319c4a7f126210f81ff878f7ece6b4e37 100644
|
| --- a/Source/bindings/dart/DartApplicationLoader.cpp
|
| +++ b/Source/bindings/dart/DartApplicationLoader.cpp
|
| @@ -60,18 +60,15 @@ DartApplicationLoader::DartApplicationLoader(
|
| Dart_Isolate isolate,
|
| Document* document,
|
| PassRefPtr<ErrorEventDispatcher> errorEventDispatcher,
|
| - PassRefPtr<VoidCallback> applicationLoadedCallback,
|
| + PassRefPtr<DartAsyncLoader> asyncLoader,
|
| bool domEnabled)
|
| : m_isolate(isolate)
|
| , m_originDocument(document)
|
| , m_errorEventDispatcher(errorEventDispatcher)
|
| , m_libraryUrl()
|
| - , m_importedLibraries()
|
| - , m_importersForSource()
|
| - , m_mainScriptHasBeenLoaded(false)
|
| , m_scriptHasError(false)
|
| - , m_applicationLoadedCallback(applicationLoadedCallback)
|
| , m_domEnabled(domEnabled)
|
| + , m_asyncLoader(asyncLoader)
|
| {
|
| ASSERT(m_originDocument);
|
| }
|
| @@ -95,117 +92,68 @@ Dart_Handle DartApplicationLoader::libraryTagHandlerCallback(Dart_LibraryTag tag
|
| // If a dart application calls spawnUri, the DartVM will call this
|
| // libraryTagHandler to canonicalize the url.
|
| // DartDOMData::current()->applicationLoader() may be 0 at this point.
|
| - return DartApplicationLoader::CanonicalizeUrl(library, urlHandle, url);
|
| + return DartUtilities::canonicalizeUrl(library, urlHandle, url);
|
| }
|
|
|
| ASSERT(DartDOMData::current()->applicationLoader());
|
| return DartDOMData::current()->applicationLoader()->libraryTagHandler(tag, library, urlHandle, url);
|
| }
|
|
|
| -Dart_Handle DartApplicationLoader::CanonicalizeUrl(Dart_Handle library, Dart_Handle urlHandle, String url)
|
| -{
|
| - if (url.startsWith("dart:") || url.startsWith("package:"))
|
| - return urlHandle;
|
| -
|
| - Dart_Handle libraryURLHandle = Dart_LibraryUrl(library);
|
| - ASSERT(!Dart_IsError(libraryURLHandle));
|
| - String libraryURL = DartUtilities::toString(libraryURLHandle);
|
| -
|
| - bool packageScheme = false;
|
| -
|
| - const char* kPackagePrefix = "package:";
|
| - const int kPackagePrefixLength = strlen(kPackagePrefix);
|
| -
|
| - const char* kHttpPrefix = "http://";
|
| - const int kHttpPrefixLength = strlen(kHttpPrefix);
|
| -
|
| - if (libraryURL.startsWith(kPackagePrefix)) {
|
| - // KURL has problems concating package:foo/bar (without slashes right after colon)
|
| - // and relative urls. Therefore pretend to be a standard absolute URL.
|
| - packageScheme = true;
|
| - libraryURL = kHttpPrefix + libraryURL.substring(kPackagePrefixLength);
|
| - }
|
| -
|
| - const KURL canonical = KURL(KURL(KURL(), libraryURL), url);
|
| - String result = canonical.string();
|
| - if (packageScheme)
|
| - result = kPackagePrefix + result.substring(kHttpPrefixLength);
|
| - return DartUtilities::stringToDartString(result);
|
| -}
|
| -
|
| Dart_Handle DartApplicationLoader::libraryTagHandler(Dart_LibraryTag tag, Dart_Handle library, Dart_Handle urlHandle, String url)
|
| {
|
| - ASSERT(url != "dart:html");
|
| -
|
| - // Record the importer.
|
| - if (tag == Dart_kImportTag)
|
| - m_importedLibraries.add(url);
|
| - else if (tag == Dart_kSourceTag) {
|
| - Dart_Handle libraryURLHandle = Dart_LibraryUrl(library);
|
| - ASSERT(!Dart_IsError(libraryURLHandle));
|
| - String libraryURL = DartUtilities::toString(libraryURLHandle);
|
| -
|
| - add(m_importersForSource, url, libraryURL);
|
| - } else
|
| + ASSERT(m_asyncLoader->contains(url));
|
| + const String& source = m_asyncLoader->get(url);
|
| +
|
| + Dart_Handle import;
|
| + if (tag == Dart_kImportTag) {
|
| + import = Dart_LoadLibrary(DartUtilities::stringToDartString(url), DartUtilities::convertSourceString(source));
|
| + } else if (tag == Dart_kSourceTag) {
|
| + import = Dart_LoadSource(library, DartUtilities::stringToDartString(url), DartUtilities::convertSourceString(source));
|
| + } else {
|
| ASSERT_NOT_REACHED();
|
| + DartUtilities::reportProblem(m_originDocument, "Invalid import tag");
|
| + return Dart_NewBoolean(false);
|
| + }
|
| +
|
| + if (Dart_IsError(import)) {
|
| + reportDartError(import);
|
| + return Dart_NewBoolean(false);
|
| + }
|
|
|
| - loadScriptResource(url);
|
| return Dart_NewBoolean(true);
|
| }
|
|
|
| -void DartApplicationLoader::load(const String& url, const String& source, WTF::OrdinalNumber startLineNumber)
|
| +void DartApplicationLoader::load(const String& url, const String& source, int startLineNumber)
|
| {
|
| DartIsolateScope isolateScope(m_isolate);
|
| DartApiScope dartApiScope;
|
| - if (m_importedLibraries.isEmpty() && m_importersForSource.isEmpty()) {
|
| - m_libraryUrl = url;
|
| - loadMainScript(url, source, startLineNumber);
|
| - m_mainScriptHasBeenLoaded = true;
|
| - } else {
|
| - ASSERT(m_importedLibraries.contains(url) || m_importersForSource.contains(url));
|
| - if (m_importedLibraries.contains(url)) {
|
| - loadLibrary(url, source);
|
| - m_importedLibraries.remove(url);
|
| - }
|
| -
|
| - if (m_importersForSource.contains(url)) {
|
| - loadSource(url, source);
|
| - m_importersForSource.remove(url);
|
| - }
|
| + m_libraryUrl = url;
|
| + loadMainScript(url, source, startLineNumber);
|
| +
|
| + uint8_t* buffer;
|
| + intptr_t size;
|
| + Dart_Handle result = Dart_CreateScriptSnapshot(&buffer, &size);
|
| + if (Dart_IsError(result)) {
|
| + reportDartError(result);
|
| + // FIXME: exiting early might be not the best option if error is due to snapshot
|
| + // creation proper (and not due to compilation), even though it's unlikely.
|
| + // Consider other options like Dart_CompileAll.
|
| + return;
|
| }
|
|
|
| - if (m_importedLibraries.isEmpty() && m_importersForSource.isEmpty() && m_mainScriptHasBeenLoaded) {
|
| - uint8_t* buffer;
|
| - intptr_t size;
|
| - Dart_Handle result = Dart_CreateScriptSnapshot(&buffer, &size);
|
| - if (Dart_IsError(result)) {
|
| - reportDartError(result);
|
| - // FIXME: exiting early might be not the best option if error is due to snapshot
|
| - // creation proper (and not due to compilation), even though it's unlikely.
|
| - // Consider other options like Dart_CompileAll.
|
| - return;
|
| - }
|
| -
|
| - Vector<uint8_t>* snapshot = DartDOMData::current()->applicationSnapshot();
|
| - ASSERT(snapshot->isEmpty());
|
| - snapshot->append(buffer, size);
|
| -
|
| - if (isSnapshottingEnabled()) {
|
| - ResourceFetcher* loader = m_originDocument->fetcher();
|
| - FetchRequest request(m_originDocument->completeURL(mainLibraryURL()), FetchInitiatorTypeNames::document);
|
| - ResourcePtr<ScriptResource> scriptResource = loader->requestScript(request);
|
| - if (scriptResource && !scriptResource->cachedMetadata(dartTypeID))
|
| - scriptResource->setCachedMetadata(dartTypeID, reinterpret_cast<const char*>(buffer), size);
|
| - }
|
| -
|
| - callEntryPoint();
|
| + Vector<uint8_t>* snapshot = DartDOMData::current()->applicationSnapshot();
|
| + ASSERT(snapshot->isEmpty());
|
| + snapshot->append(buffer, size);
|
| +
|
| + if (isSnapshottingEnabled()) {
|
| + ResourceFetcher* loader = m_originDocument->fetcher();
|
| + FetchRequest request(m_originDocument->completeURL(mainLibraryURL()), FetchInitiatorTypeNames::document);
|
| + ResourcePtr<ScriptResource> scriptResource = loader->requestScript(request);
|
| + if (scriptResource && !scriptResource->cachedMetadata(dartTypeID))
|
| + scriptResource->setCachedMetadata(dartTypeID, reinterpret_cast<const char*>(buffer), size);
|
| }
|
| -}
|
|
|
| -static Dart_Handle convertSourceString(const String& source)
|
| -{
|
| - const CString utf8encoded = source.utf8();
|
| - return Dart_NewStringFromCString(utf8encoded.data());
|
| + callEntryPoint();
|
| }
|
|
|
| void DartApplicationLoader::installLibraryTagHandlerForCurrentIsolate()
|
| @@ -215,7 +163,7 @@ void DartApplicationLoader::installLibraryTagHandlerForCurrentIsolate()
|
| UNUSED_PARAM(result);
|
| }
|
|
|
| -void DartApplicationLoader::loadMainScript(const String& url, const String& source, WTF::OrdinalNumber startLineNumber)
|
| +void DartApplicationLoader::loadMainScript(const String& url, const String& source, int lineOffset)
|
| {
|
| // Associate application loader with current isolate, so we can retrieve it
|
| // in libraryTagHandlerCallback.
|
| @@ -226,9 +174,10 @@ void DartApplicationLoader::loadMainScript(const String& url, const String& sour
|
| // inserted by the parser (e.g. it was inserted by JavaScript or Dart code.
|
| // We should not pass the Dart VM a negative line number so we fall back to
|
| // passing in line number zero for that case.
|
| - intptr_t lineOffset = startLineNumber == OrdinalNumber::beforeFirst() ? 0 : startLineNumber.zeroBasedInt();
|
| + if (lineOffset < 0)
|
| + lineOffset = 0;
|
|
|
| - Dart_Handle dartSource = convertSourceString(source);
|
| + Dart_Handle dartSource = DartUtilities::convertSourceString(source);
|
|
|
| if (m_domEnabled) {
|
| // The main page already should have an isolate. Load this script as a top-level library.
|
| @@ -258,8 +207,6 @@ void DartApplicationLoader::loadMainScript(const String& url, const String& sour
|
| void DartApplicationLoader::loadScriptFromSnapshot(const String& url, const uint8_t* snapshot, intptr_t snapshotSize)
|
| {
|
| Timeline timeline(m_originDocument->frame(), String("loadSnapshot@") + m_libraryUrl);
|
| - ASSERT(m_importedLibraries.isEmpty());
|
| - ASSERT(m_importersForSource.isEmpty());
|
| m_libraryUrl = url;
|
| DartIsolateScope isolateScope(m_isolate);
|
| DartApiScope apiScope;
|
| @@ -271,52 +218,28 @@ void DartApplicationLoader::loadScriptFromSnapshot(const String& url, const uint
|
| callEntryPoint();
|
| }
|
|
|
| -void DartApplicationLoader::loadSource(const String& url, const String& source)
|
| -{
|
| - ASSERT(m_importersForSource.contains(url));
|
| - const UrlSet* importers = m_importersForSource.find(url)->value;
|
| - Dart_Handle dartUrl = DartUtilities::stringToDartString(url);
|
| - Dart_Handle dartSource = convertSourceString(source);
|
| - for (UrlSet::iterator iter = importers->begin(); iter != importers->end(); ++iter) {
|
| - Dart_Handle library = Dart_LookupLibrary(DartUtilities::stringToDartString(*iter));
|
| - if (Dart_IsError(library)) {
|
| - reportDartError(library);
|
| - return;
|
| - }
|
| - Dart_Handle result = Dart_LoadSource(library, dartUrl, dartSource);
|
| - if (Dart_IsError(result)) {
|
| - reportDartError(result);
|
| - return;
|
| - }
|
| - }
|
| -}
|
| -
|
| void DartApplicationLoader::loadLibrary(const String& url, const String& source)
|
| {
|
| - ASSERT(m_importedLibraries.contains(url));
|
| - Dart_Handle result = Dart_LoadLibrary(DartUtilities::stringToDartString(url), convertSourceString(source));
|
| + Dart_Handle result = Dart_LoadLibrary(DartUtilities::stringToDartString(url), DartUtilities::convertSourceString(source));
|
| if (Dart_IsError(result))
|
| reportDartError(result);
|
| }
|
|
|
| void DartApplicationLoader::callEntryPoint()
|
| {
|
| - RefPtr<DartApplicationLoader> guard(this);
|
| -
|
| Timeline timeline(m_originDocument->frame(), String("callEntryPoint@") + m_libraryUrl);
|
| ASSERT(m_originDocument->readyState() != "loading");
|
| if (m_domEnabled) {
|
| Timeline timeline(m_originDocument->frame(), String("notifyDebugServer@") + m_libraryUrl);
|
| DartDebugServer::shared().isolateLoaded();
|
| }
|
| +
|
| + // FIXME: Do we still need this?
|
| if (m_scriptHasError) {
|
| // Errors have already been printed to console.
|
| return;
|
| }
|
|
|
| - if (m_applicationLoadedCallback)
|
| - m_applicationLoadedCallback->handleEvent();
|
| -
|
| if (m_domEnabled) {
|
| V8Scope v8scope;
|
| Dart_Handle result = Dart_Invoke(topLevelLibrary(), Dart_NewStringFromCString("main"), 0, 0);
|
| @@ -335,89 +258,6 @@ Dart_Handle DartApplicationLoader::topLevelLibrary()
|
| return library;
|
| }
|
|
|
| -class ScriptLoadCallback : public ResourceClient {
|
| -public:
|
| - ScriptLoadCallback(String url, PassRefPtr<DartApplicationLoader> 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->scriptLoadError(m_url);
|
| - else if (cachedResource->wasCanceled()) {
|
| - // FIXME: shall we let VM know, so it can inform application some of its
|
| - // resources cannot be loaded?
|
| - } else {
|
| - ScriptSourceCode sourceCode(m_scriptResource.get());
|
| - CachedMetadata* cachedMetadata = m_scriptResource->cachedMetadata(dartTypeID);
|
| - if (cachedMetadata)
|
| - m_loader->loadScriptFromSnapshot(sourceCode.url(), reinterpret_cast<const uint8_t*>(cachedMetadata->data()), static_cast<intptr_t>(cachedMetadata->size()));
|
| - else {
|
| - // Use the original url associated with the Script so that
|
| - // redirects do not break the DartApplicationLoader.
|
| - // 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->load(m_url, sourceCode.source(), WTF::OrdinalNumber::first());
|
| - }
|
| - }
|
| -
|
| - m_scriptResource->removeClient(this);
|
| - delete this;
|
| - }
|
| -
|
| - private:
|
| - String m_url;
|
| - RefPtr<DartApplicationLoader> 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 DartApplicationLoader::loadScriptResource(const String& url)
|
| -{
|
| - // Request loading of script dependencies.
|
| - FetchRequest request(m_originDocument->completeURL(resolveUrl(mainLibraryURL(), url)), FetchInitiatorTypeNames::document, "utf8");
|
| - // FIXME: what about charset for this script, maybe use charset of initial script tag?
|
| - ResourcePtr<ScriptResource> scriptResource = m_originDocument->fetcher()->requestScript(request);
|
| - if (scriptResource)
|
| - scriptResource->addClient(new ScriptLoadCallback(m_originDocument->completeURL(url), this, scriptResource));
|
| - else
|
| - scriptLoadError(url);
|
| -}
|
| -
|
| void DartApplicationLoader::scriptLoadError(String failedUrl)
|
| {
|
| // FIXME: try to dig out line number, -1 for now.
|
| @@ -429,15 +269,4 @@ void DartApplicationLoader::scriptLoadError(String failedUrl)
|
| m_errorEventDispatcher->dispatchErrorEvent();
|
| }
|
|
|
| -void DartApplicationLoader::add(UrlMultiMap& map, const String& key, const String& value)
|
| -{
|
| - // We should never have a self dependence.
|
| - ASSERT(key != value);
|
| - UrlMultiMap::iterator iter = map.find(key);
|
| - if (iter == map.end())
|
| - iter = map.add(key, new UrlSet()).iterator;
|
| - UrlSet* set = iter->value;
|
| - set->add(value);
|
| -}
|
| -
|
| }
|
|
|