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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/bindings/dart/DartAsyncLoader.h ('k') | Source/bindings/dart/DartController.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 #include "config.h"
31 #include "bindings/dart/DartAsyncLoader.h"
32
33 #include "FetchInitiatorTypeNames.h"
34 #include "bindings/dart/DartUtilities.h"
35 #include "bindings/v8/ScriptSourceCode.h"
36 #include "core/dom/Document.h"
37 #include "core/dom/ScriptLoader.h"
38 #include "core/fetch/FetchRequest.h"
39 #include "core/fetch/ResourceClient.h"
40 #include "core/fetch/ResourceFetcher.h"
41 #include "core/fetch/ScriptResource.h"
42 #include "core/inspector/ScriptCallStack.h"
43
44 #include <dart_api.h>
45
46 namespace WebCore {
47
48 static const unsigned dartTypeID = 0xDAADDAAD;
49
50 void DartAsyncLoader::LoadCallback::reportError(const String& error, const Strin g& url)
51 {
52 m_originDocument->logExceptionToConsole(error + ": " + url, url, 0, 0, 0);
53 if (m_scriptLoader)
54 m_scriptLoader->dispatchErrorEvent();
55 }
56
57 ResourcePtr<ScriptResource> DartAsyncLoader::LoadCallback::requestScript(FetchRe quest& request)
58 {
59 return m_originDocument->fetcher()->requestScript(request);
60 }
61
62
63 DartAsyncLoader::DartAsyncLoader(const String& url, PassRefPtr<DartAsyncLoader:: LoadCallback> loadCallback)
64 : m_loadCallback(loadCallback)
65 , m_mainScriptFetched(false)
66 {
67 Document* document = m_loadCallback->document();
68 char* error;
69
70 const KURL canonical = KURL(document->baseURL(), url);
71 m_topUrl = canonical.string();
72
73 DartDOMData* domData = new DartDOMData(document, false);
74 domData->setAsyncLoader(adoptRef(this));
75
76 const uint8_t* snapshot = DartUtilities::fullSnapshot(document->frame());
77 m_parseIsolate = Dart_CreateIsolate("dartium.fetch", "", snapshot, domData, &error);
78 if (!m_parseIsolate)
79 m_loadCallback->reportError(error, url);
80
81 Dart_Handle result = Dart_SetLibraryTagHandler(&libraryTagHandlerCallback);
82 ASSERT(!Dart_IsError(result));
83 UNUSED_PARAM(result);
84
85 m_pendingLibraries.add(m_topUrl);
86 }
87
88 DartAsyncLoader::~DartAsyncLoader()
89 {
90 m_loadCallback = 0;
91 }
92
93 void DartAsyncLoader::findDependences(const String& url, const String& source, i ntptr_t lineNumber)
94 {
95 ASSERT(m_pendingLibraries.contains(url) || m_pendingSource.contains(url));
96
97 DartIsolateScope isolateScope(m_parseIsolate);
98 DartApiScope dartApiScope;
99
100 if (!m_mainScriptFetched) {
101 ASSERT(m_topUrl == url);
102 m_topSource = source;
103 m_lineNumber = lineNumber;
104 m_mainScriptFetched = true;
105 }
106
107 if (m_pendingLibraries.contains(url)) {
108 processLibrary(url, source);
109 m_pendingLibraries.remove(url);
110 } else {
111 ASSERT(m_pendingSource.contains(url));
112 // No imports or parts, so no need to process further.
113 m_pendingSource.remove(url);
114 }
115 }
116
117 void DartAsyncLoader::reportError(Dart_Handle error, const String& url)
118 {
119 reportError(Dart_GetError(error), url);
120 }
121
122 void DartAsyncLoader::processLibrary(const String& url, const String& source)
123 {
124 ASSERT(m_pendingLibraries.contains(url));
125
126 Dart_Handle result = Dart_LoadLibrary(DartUtilities::stringToDartString(url) , DartUtilities::convertSourceString(source));
127 if (Dart_IsError(result))
128 reportError(result, url);
129 }
130
131 void DartAsyncLoader::process(const String& url, const String& source, intptr_t lineNumber)
132 {
133 ASSERT(!m_urlSourceMap.contains(url));
134 m_urlSourceMap.add(url, source);
135
136 findDependences(url, source, lineNumber);
137 if (ready()) {
138 // All dependences are in.
139 RefPtr<DartAsyncLoader> guard(this);
140 m_loadCallback->ready(guard);
141
142 // Free this loader and its isolate.
143 Dart_EnterIsolate(m_parseIsolate);
144 DartDOMData::current()->setAsyncLoader(0);
145 Dart_ShutdownIsolate();
146 }
147 }
148
149 Dart_Handle DartAsyncLoader::libraryTagHandlerCallback(Dart_LibraryTag tag, Dart _Handle library, Dart_Handle urlHandle)
150 {
151 ASSERT(Dart_CurrentIsolate());
152 ASSERT(Dart_IsLibrary(library));
153
154 const String url = DartUtilities::toString(urlHandle);
155
156 if (tag == Dart_kCanonicalizeUrl) {
157 // If a dart application calls spawnUri, the DartVM will call this
158 // libraryTagHandler to canonicalize the url.
159 // DartDOMData::current()->scriptLoader() may be 0 at this point.
160 return DartUtilities::canonicalizeUrl(library, urlHandle, url);
161 }
162
163 RefPtr<DartAsyncLoader> loader = DartDOMData::current()->asyncLoader();
164 ASSERT(loader);
165
166 if (!url.startsWith("dart:")) {
167 // Fetch non-system URLs.
168 if (tag == Dart_kImportTag) {
169 loader->m_pendingLibraries.add(url);
170 } else if (tag == Dart_kSourceTag) {
171 loader->m_pendingSource.add(url);
172 } else {
173 ASSERT_NOT_REACHED();
174 }
175 loader->fetchScriptResource(url);
176 }
177 return Dart_NewBoolean(true);
178 }
179
180 class ScriptLoadedCallback : public ResourceClient {
181 public:
182 ScriptLoadedCallback(String url, PassRefPtr<DartAsyncLoader> loader, Resourc ePtr<ScriptResource> scriptResource)
183 : m_url(url)
184 , m_loader(loader)
185 , m_scriptResource(scriptResource)
186 {
187 }
188
189 virtual void notifyFinished(Resource* cachedResource)
190 {
191 ASSERT(cachedResource->type() == Resource::Script);
192 ASSERT(cachedResource == m_scriptResource.get());
193 ASSERT(WTF::isMainThread());
194
195 if (cachedResource->errorOccurred()) {
196 m_loader->reportError(String("An error occurred loading file"), m_ur l);
197 } else if (cachedResource->wasCanceled()) {
198 // FIXME: shall we let VM know, so it can inform application some of its
199 // resources cannot be loaded?
200 m_loader->reportError(String("File request cancelled"), m_url);
201 } else {
202 ScriptSourceCode sourceCode(m_scriptResource.get());
203 // FIXME: Should we check for cached metadata?
204 // CachedMetadata* cachedMetadata = m_scriptResource->cachedMetadata (dartTypeID);
205
206 // Use the original url associated with the Script so that
207 // redirects do not break the DartScriptLoader.
208 // FIXME: is this the correct behavior? This functionality is
209 // very convenient when you want the source file to act as if
210 // it was from the original location but that isn't always
211 // what the user expects.
212 m_loader->process(m_url, sourceCode.source(), 0);
213 }
214
215 m_scriptResource->removeClient(this);
216 delete this;
217 }
218
219 private:
220 String m_url;
221 RefPtr<DartAsyncLoader> m_loader;
222 ResourcePtr<ScriptResource> m_scriptResource;
223 };
224
225 static String resolveUrl(String mainLibraryURL, const String& url)
226 {
227 if (!url.startsWith("package:") || url.startsWith("package://"))
228 return url;
229
230 String packageRoot;
231 String packageUrl;
232 if (const char* packageRootOverride = getenv("DART_PACKAGE_ROOT")) {
233 // Resolve with respect to the override. Append a
234 // slash to ensure that resolution is against this
235 // path and not its parent.
236 packageRoot = String(packageRootOverride) + "/";
237 // Strip the 'package:' prefix.
238 packageUrl = url.substring(8);
239 } else {
240 // Resolve with respect to the entry point's URL. Note, the
241 // trailing file name in the entry point URL (e.g.,
242 // 'rootpath/mainapp.dart') is stripped by the KURL
243 // constructor below.
244 packageRoot = mainLibraryURL;
245 packageUrl = String("packages/") + url.substring(8);
246 }
247 return KURL(KURL(KURL(), packageRoot), packageUrl).string();
248 }
249
250 void DartAsyncLoader::fetchScriptResource(const String& url)
251 {
252 // Request loading of script dependencies.
253 FetchRequest request(m_loadCallback->completeURL(resolveUrl(m_topUrl, url)),
254 FetchInitiatorTypeNames::document, "utf8");
255 // FIXME: what about charset for this script, maybe use charset of initial s cript tag?
256 ResourcePtr<ScriptResource> scriptResource = m_loadCallback->requestScript(r equest);
257 if (scriptResource)
258 scriptResource->addClient(new ScriptLoadedCallback(m_loadCallback->compl eteURL(url), this, scriptResource));
259 else
260 m_loadCallback->reportError(String("File request error"), url);
261 }
262
263 }
OLDNEW
« 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