OLD | NEW |
1 // Copyright (c) 2009, Google Inc. | 1 // Copyright (c) 2009, Google Inc. |
2 // All rights reserved. | 2 // All rights reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 | 53 |
54 static bool isSnapshottingEnabled() | 54 static bool isSnapshottingEnabled() |
55 { | 55 { |
56 return getenv("DART_SNAPSHOTTING_ENABLED"); | 56 return getenv("DART_SNAPSHOTTING_ENABLED"); |
57 } | 57 } |
58 | 58 |
59 DartApplicationLoader::DartApplicationLoader( | 59 DartApplicationLoader::DartApplicationLoader( |
60 Dart_Isolate isolate, | 60 Dart_Isolate isolate, |
61 Document* document, | 61 Document* document, |
62 PassRefPtr<ErrorEventDispatcher> errorEventDispatcher, | 62 PassRefPtr<ErrorEventDispatcher> errorEventDispatcher, |
63 PassRefPtr<VoidCallback> applicationLoadedCallback, | 63 PassRefPtr<DartAsyncLoader> asyncLoader, |
64 bool domEnabled) | 64 bool domEnabled) |
65 : m_isolate(isolate) | 65 : m_isolate(isolate) |
66 , m_originDocument(document) | 66 , m_originDocument(document) |
67 , m_errorEventDispatcher(errorEventDispatcher) | 67 , m_errorEventDispatcher(errorEventDispatcher) |
68 , m_libraryUrl() | 68 , m_libraryUrl() |
69 , m_importedLibraries() | |
70 , m_importersForSource() | |
71 , m_mainScriptHasBeenLoaded(false) | |
72 , m_scriptHasError(false) | 69 , m_scriptHasError(false) |
73 , m_applicationLoadedCallback(applicationLoadedCallback) | |
74 , m_domEnabled(domEnabled) | 70 , m_domEnabled(domEnabled) |
| 71 , m_asyncLoader(asyncLoader) |
75 { | 72 { |
76 ASSERT(m_originDocument); | 73 ASSERT(m_originDocument); |
77 } | 74 } |
78 | 75 |
79 static const unsigned dartTypeID = 0xDAADDAAD; | 76 static const unsigned dartTypeID = 0xDAADDAAD; |
80 | 77 |
81 void DartApplicationLoader::reportDartError(Dart_Handle error) | 78 void DartApplicationLoader::reportDartError(Dart_Handle error) |
82 { | 79 { |
83 m_scriptHasError = true; | 80 m_scriptHasError = true; |
84 DartUtilities::reportProblem(m_originDocument, error, m_libraryUrl); | 81 DartUtilities::reportProblem(m_originDocument, error, m_libraryUrl); |
85 } | 82 } |
86 | 83 |
87 Dart_Handle DartApplicationLoader::libraryTagHandlerCallback(Dart_LibraryTag tag
, Dart_Handle library, Dart_Handle urlHandle) | 84 Dart_Handle DartApplicationLoader::libraryTagHandlerCallback(Dart_LibraryTag tag
, Dart_Handle library, Dart_Handle urlHandle) |
88 { | 85 { |
89 ASSERT(Dart_CurrentIsolate()); | 86 ASSERT(Dart_CurrentIsolate()); |
90 ASSERT(Dart_IsLibrary(library)); | 87 ASSERT(Dart_IsLibrary(library)); |
91 | 88 |
92 const String url = DartUtilities::toString(urlHandle); | 89 const String url = DartUtilities::toString(urlHandle); |
93 | 90 |
94 if (tag == Dart_kCanonicalizeUrl) { | 91 if (tag == Dart_kCanonicalizeUrl) { |
95 // If a dart application calls spawnUri, the DartVM will call this | 92 // If a dart application calls spawnUri, the DartVM will call this |
96 // libraryTagHandler to canonicalize the url. | 93 // libraryTagHandler to canonicalize the url. |
97 // DartDOMData::current()->applicationLoader() may be 0 at this point. | 94 // DartDOMData::current()->applicationLoader() may be 0 at this point. |
98 return DartApplicationLoader::CanonicalizeUrl(library, urlHandle, url); | 95 return DartUtilities::canonicalizeUrl(library, urlHandle, url); |
99 } | 96 } |
100 | 97 |
101 ASSERT(DartDOMData::current()->applicationLoader()); | 98 ASSERT(DartDOMData::current()->applicationLoader()); |
102 return DartDOMData::current()->applicationLoader()->libraryTagHandler(tag, l
ibrary, urlHandle, url); | 99 return DartDOMData::current()->applicationLoader()->libraryTagHandler(tag, l
ibrary, urlHandle, url); |
103 } | 100 } |
104 | 101 |
105 Dart_Handle DartApplicationLoader::CanonicalizeUrl(Dart_Handle library, Dart_Han
dle urlHandle, String url) | 102 Dart_Handle DartApplicationLoader::libraryTagHandler(Dart_LibraryTag tag, Dart_H
andle library, Dart_Handle urlHandle, String url) |
106 { | 103 { |
107 if (url.startsWith("dart:") || url.startsWith("package:")) | 104 ASSERT(m_asyncLoader->contains(url)); |
108 return urlHandle; | 105 const String& source = m_asyncLoader->get(url); |
109 | 106 |
110 Dart_Handle libraryURLHandle = Dart_LibraryUrl(library); | 107 Dart_Handle import; |
111 ASSERT(!Dart_IsError(libraryURLHandle)); | 108 if (tag == Dart_kImportTag) { |
112 String libraryURL = DartUtilities::toString(libraryURLHandle); | 109 import = Dart_LoadLibrary(DartUtilities::stringToDartString(url), DartUt
ilities::convertSourceString(source)); |
113 | 110 } else if (tag == Dart_kSourceTag) { |
114 bool packageScheme = false; | 111 import = Dart_LoadSource(library, DartUtilities::stringToDartString(url)
, DartUtilities::convertSourceString(source)); |
115 | 112 } else { |
116 const char* kPackagePrefix = "package:"; | 113 ASSERT_NOT_REACHED(); |
117 const int kPackagePrefixLength = strlen(kPackagePrefix); | 114 DartUtilities::reportProblem(m_originDocument, "Invalid import tag"); |
118 | 115 return Dart_NewBoolean(false); |
119 const char* kHttpPrefix = "http://"; | |
120 const int kHttpPrefixLength = strlen(kHttpPrefix); | |
121 | |
122 if (libraryURL.startsWith(kPackagePrefix)) { | |
123 // KURL has problems concating package:foo/bar (without slashes right af
ter colon) | |
124 // and relative urls. Therefore pretend to be a standard absolute URL. | |
125 packageScheme = true; | |
126 libraryURL = kHttpPrefix + libraryURL.substring(kPackagePrefixLength); | |
127 } | 116 } |
128 | 117 |
129 const KURL canonical = KURL(KURL(KURL(), libraryURL), url); | 118 if (Dart_IsError(import)) { |
130 String result = canonical.string(); | 119 reportDartError(import); |
131 if (packageScheme) | 120 return Dart_NewBoolean(false); |
132 result = kPackagePrefix + result.substring(kHttpPrefixLength); | 121 } |
133 return DartUtilities::stringToDartString(result); | |
134 } | |
135 | 122 |
136 Dart_Handle DartApplicationLoader::libraryTagHandler(Dart_LibraryTag tag, Dart_H
andle library, Dart_Handle urlHandle, String url) | |
137 { | |
138 ASSERT(url != "dart:html"); | |
139 | |
140 // Record the importer. | |
141 if (tag == Dart_kImportTag) | |
142 m_importedLibraries.add(url); | |
143 else if (tag == Dart_kSourceTag) { | |
144 Dart_Handle libraryURLHandle = Dart_LibraryUrl(library); | |
145 ASSERT(!Dart_IsError(libraryURLHandle)); | |
146 String libraryURL = DartUtilities::toString(libraryURLHandle); | |
147 | |
148 add(m_importersForSource, url, libraryURL); | |
149 } else | |
150 ASSERT_NOT_REACHED(); | |
151 | |
152 loadScriptResource(url); | |
153 return Dart_NewBoolean(true); | 123 return Dart_NewBoolean(true); |
154 } | 124 } |
155 | 125 |
156 void DartApplicationLoader::load(const String& url, const String& source, WTF::O
rdinalNumber startLineNumber) | 126 void DartApplicationLoader::load(const String& url, const String& source, int st
artLineNumber) |
157 { | 127 { |
158 DartIsolateScope isolateScope(m_isolate); | 128 DartIsolateScope isolateScope(m_isolate); |
159 DartApiScope dartApiScope; | 129 DartApiScope dartApiScope; |
160 if (m_importedLibraries.isEmpty() && m_importersForSource.isEmpty()) { | 130 m_libraryUrl = url; |
161 m_libraryUrl = url; | 131 loadMainScript(url, source, startLineNumber); |
162 loadMainScript(url, source, startLineNumber); | |
163 m_mainScriptHasBeenLoaded = true; | |
164 } else { | |
165 ASSERT(m_importedLibraries.contains(url) || m_importersForSource.contain
s(url)); | |
166 if (m_importedLibraries.contains(url)) { | |
167 loadLibrary(url, source); | |
168 m_importedLibraries.remove(url); | |
169 } | |
170 | 132 |
171 if (m_importersForSource.contains(url)) { | 133 uint8_t* buffer; |
172 loadSource(url, source); | 134 intptr_t size; |
173 m_importersForSource.remove(url); | 135 Dart_Handle result = Dart_CreateScriptSnapshot(&buffer, &size); |
174 } | 136 if (Dart_IsError(result)) { |
| 137 reportDartError(result); |
| 138 // FIXME: exiting early might be not the best option if error is due to
snapshot |
| 139 // creation proper (and not due to compilation), even though it's unlike
ly. |
| 140 // Consider other options like Dart_CompileAll. |
| 141 return; |
175 } | 142 } |
176 | 143 |
177 if (m_importedLibraries.isEmpty() && m_importersForSource.isEmpty() && m_mai
nScriptHasBeenLoaded) { | 144 Vector<uint8_t>* snapshot = DartDOMData::current()->applicationSnapshot(); |
178 uint8_t* buffer; | 145 ASSERT(snapshot->isEmpty()); |
179 intptr_t size; | 146 snapshot->append(buffer, size); |
180 Dart_Handle result = Dart_CreateScriptSnapshot(&buffer, &size); | |
181 if (Dart_IsError(result)) { | |
182 reportDartError(result); | |
183 // FIXME: exiting early might be not the best option if error is due
to snapshot | |
184 // creation proper (and not due to compilation), even though it's un
likely. | |
185 // Consider other options like Dart_CompileAll. | |
186 return; | |
187 } | |
188 | 147 |
189 Vector<uint8_t>* snapshot = DartDOMData::current()->applicationSnapshot(
); | 148 if (isSnapshottingEnabled()) { |
190 ASSERT(snapshot->isEmpty()); | 149 ResourceFetcher* loader = m_originDocument->fetcher(); |
191 snapshot->append(buffer, size); | 150 FetchRequest request(m_originDocument->completeURL(mainLibraryURL()), Fe
tchInitiatorTypeNames::document); |
| 151 ResourcePtr<ScriptResource> scriptResource = loader->requestScript(reque
st); |
| 152 if (scriptResource && !scriptResource->cachedMetadata(dartTypeID)) |
| 153 scriptResource->setCachedMetadata(dartTypeID, reinterpret_cast<const
char*>(buffer), size); |
| 154 } |
192 | 155 |
193 if (isSnapshottingEnabled()) { | 156 callEntryPoint(); |
194 ResourceFetcher* loader = m_originDocument->fetcher(); | |
195 FetchRequest request(m_originDocument->completeURL(mainLibraryURL())
, FetchInitiatorTypeNames::document); | |
196 ResourcePtr<ScriptResource> scriptResource = loader->requestScript(r
equest); | |
197 if (scriptResource && !scriptResource->cachedMetadata(dartTypeID)) | |
198 scriptResource->setCachedMetadata(dartTypeID, reinterpret_cast<c
onst char*>(buffer), size); | |
199 } | |
200 | |
201 callEntryPoint(); | |
202 } | |
203 } | |
204 | |
205 static Dart_Handle convertSourceString(const String& source) | |
206 { | |
207 const CString utf8encoded = source.utf8(); | |
208 return Dart_NewStringFromCString(utf8encoded.data()); | |
209 } | 157 } |
210 | 158 |
211 void DartApplicationLoader::installLibraryTagHandlerForCurrentIsolate() | 159 void DartApplicationLoader::installLibraryTagHandlerForCurrentIsolate() |
212 { | 160 { |
213 Dart_Handle result = Dart_SetLibraryTagHandler(&libraryTagHandlerCallback); | 161 Dart_Handle result = Dart_SetLibraryTagHandler(&libraryTagHandlerCallback); |
214 ASSERT(!Dart_IsError(result)); | 162 ASSERT(!Dart_IsError(result)); |
215 UNUSED_PARAM(result); | 163 UNUSED_PARAM(result); |
216 } | 164 } |
217 | 165 |
218 void DartApplicationLoader::loadMainScript(const String& url, const String& sour
ce, WTF::OrdinalNumber startLineNumber) | 166 void DartApplicationLoader::loadMainScript(const String& url, const String& sour
ce, int lineOffset) |
219 { | 167 { |
220 // Associate application loader with current isolate, so we can retrieve it | 168 // Associate application loader with current isolate, so we can retrieve it |
221 // in libraryTagHandlerCallback. | 169 // in libraryTagHandlerCallback. |
222 DartDOMData::current()->setApplicationLoader(this); | 170 DartDOMData::current()->setApplicationLoader(this); |
223 installLibraryTagHandlerForCurrentIsolate(); | 171 installLibraryTagHandlerForCurrentIsolate(); |
224 | 172 |
225 // startLineNumber == OrdinalNumber::beforeFirst() if the script was not | 173 // startLineNumber == OrdinalNumber::beforeFirst() if the script was not |
226 // inserted by the parser (e.g. it was inserted by JavaScript or Dart code. | 174 // inserted by the parser (e.g. it was inserted by JavaScript or Dart code. |
227 // We should not pass the Dart VM a negative line number so we fall back to | 175 // We should not pass the Dart VM a negative line number so we fall back to |
228 // passing in line number zero for that case. | 176 // passing in line number zero for that case. |
229 intptr_t lineOffset = startLineNumber == OrdinalNumber::beforeFirst() ? 0 :
startLineNumber.zeroBasedInt(); | 177 if (lineOffset < 0) |
| 178 lineOffset = 0; |
230 | 179 |
231 Dart_Handle dartSource = convertSourceString(source); | 180 Dart_Handle dartSource = DartUtilities::convertSourceString(source); |
232 | 181 |
233 if (m_domEnabled) { | 182 if (m_domEnabled) { |
234 // The main page already should have an isolate. Load this script as a t
op-level library. | 183 // The main page already should have an isolate. Load this script as a t
op-level library. |
235 | 184 |
236 // FIXME(dartbug.com/13301): Hoist this out once we support multiple scr
ipt tags per isolate. | 185 // FIXME(dartbug.com/13301): Hoist this out once we support multiple scr
ipt tags per isolate. |
237 String scriptUrl = url + "$script"; | 186 String scriptUrl = url + "$script"; |
238 Dart_Handle script = Dart_LoadScript(DartUtilities::stringToDartString(s
criptUrl), Dart_NewStringFromCString(""), 0, 0); | 187 Dart_Handle script = Dart_LoadScript(DartUtilities::stringToDartString(s
criptUrl), Dart_NewStringFromCString(""), 0, 0); |
239 if (Dart_IsError(script)) | 188 if (Dart_IsError(script)) |
240 DartUtilities::reportProblem(m_originDocument, script, m_libraryUrl)
; | 189 DartUtilities::reportProblem(m_originDocument, script, m_libraryUrl)
; |
241 | 190 |
242 // FIXME(dartbug.com/13460): We need to record the lineOffset and column
Offset. | 191 // FIXME(dartbug.com/13460): We need to record the lineOffset and column
Offset. |
243 Dart_Handle library = Dart_LoadLibrary(DartUtilities::stringToDartString
(url), dartSource); | 192 Dart_Handle library = Dart_LoadLibrary(DartUtilities::stringToDartString
(url), dartSource); |
244 if (Dart_IsError(library)) | 193 if (Dart_IsError(library)) |
245 DartUtilities::reportProblem(m_originDocument, library, m_libraryUrl
); | 194 DartUtilities::reportProblem(m_originDocument, library, m_libraryUrl
); |
246 | 195 |
247 Dart_Handle result = Dart_LibraryImportLibrary(script, library, Dart_Nul
l()); | 196 Dart_Handle result = Dart_LibraryImportLibrary(script, library, Dart_Nul
l()); |
248 if (Dart_IsError(result)) | 197 if (Dart_IsError(result)) |
249 DartUtilities::reportProblem(m_originDocument, result, m_libraryUrl)
; | 198 DartUtilities::reportProblem(m_originDocument, result, m_libraryUrl)
; |
250 } else { | 199 } else { |
251 // This is a background isolate. Load as a top-level script. | 200 // This is a background isolate. Load as a top-level script. |
252 Dart_Handle script = Dart_LoadScript(DartUtilities::stringToDartString(u
rl), dartSource, lineOffset, 0); | 201 Dart_Handle script = Dart_LoadScript(DartUtilities::stringToDartString(u
rl), dartSource, lineOffset, 0); |
253 if (Dart_IsError(script)) | 202 if (Dart_IsError(script)) |
254 DartUtilities::reportProblem(m_originDocument, script, m_libraryUrl)
; | 203 DartUtilities::reportProblem(m_originDocument, script, m_libraryUrl)
; |
255 } | 204 } |
256 } | 205 } |
257 | 206 |
258 void DartApplicationLoader::loadScriptFromSnapshot(const String& url, const uint
8_t* snapshot, intptr_t snapshotSize) | 207 void DartApplicationLoader::loadScriptFromSnapshot(const String& url, const uint
8_t* snapshot, intptr_t snapshotSize) |
259 { | 208 { |
260 Timeline timeline(m_originDocument->frame(), String("loadSnapshot@") + m_lib
raryUrl); | 209 Timeline timeline(m_originDocument->frame(), String("loadSnapshot@") + m_lib
raryUrl); |
261 ASSERT(m_importedLibraries.isEmpty()); | |
262 ASSERT(m_importersForSource.isEmpty()); | |
263 m_libraryUrl = url; | 210 m_libraryUrl = url; |
264 DartIsolateScope isolateScope(m_isolate); | 211 DartIsolateScope isolateScope(m_isolate); |
265 DartApiScope apiScope; | 212 DartApiScope apiScope; |
266 Dart_Handle result = Dart_LoadScriptFromSnapshot(snapshot, snapshotSize); | 213 Dart_Handle result = Dart_LoadScriptFromSnapshot(snapshot, snapshotSize); |
267 if (Dart_IsError(result)) { | 214 if (Dart_IsError(result)) { |
268 reportDartError(result); | 215 reportDartError(result); |
269 return; | 216 return; |
270 } | 217 } |
271 callEntryPoint(); | 218 callEntryPoint(); |
272 } | 219 } |
273 | 220 |
274 void DartApplicationLoader::loadSource(const String& url, const String& source) | |
275 { | |
276 ASSERT(m_importersForSource.contains(url)); | |
277 const UrlSet* importers = m_importersForSource.find(url)->value; | |
278 Dart_Handle dartUrl = DartUtilities::stringToDartString(url); | |
279 Dart_Handle dartSource = convertSourceString(source); | |
280 for (UrlSet::iterator iter = importers->begin(); iter != importers->end(); +
+iter) { | |
281 Dart_Handle library = Dart_LookupLibrary(DartUtilities::stringToDartStri
ng(*iter)); | |
282 if (Dart_IsError(library)) { | |
283 reportDartError(library); | |
284 return; | |
285 } | |
286 Dart_Handle result = Dart_LoadSource(library, dartUrl, dartSource); | |
287 if (Dart_IsError(result)) { | |
288 reportDartError(result); | |
289 return; | |
290 } | |
291 } | |
292 } | |
293 | |
294 void DartApplicationLoader::loadLibrary(const String& url, const String& source) | 221 void DartApplicationLoader::loadLibrary(const String& url, const String& source) |
295 { | 222 { |
296 ASSERT(m_importedLibraries.contains(url)); | 223 Dart_Handle result = Dart_LoadLibrary(DartUtilities::stringToDartString(url)
, DartUtilities::convertSourceString(source)); |
297 Dart_Handle result = Dart_LoadLibrary(DartUtilities::stringToDartString(url)
, convertSourceString(source)); | |
298 if (Dart_IsError(result)) | 224 if (Dart_IsError(result)) |
299 reportDartError(result); | 225 reportDartError(result); |
300 } | 226 } |
301 | 227 |
302 void DartApplicationLoader::callEntryPoint() | 228 void DartApplicationLoader::callEntryPoint() |
303 { | 229 { |
304 RefPtr<DartApplicationLoader> guard(this); | |
305 | |
306 Timeline timeline(m_originDocument->frame(), String("callEntryPoint@") + m_l
ibraryUrl); | 230 Timeline timeline(m_originDocument->frame(), String("callEntryPoint@") + m_l
ibraryUrl); |
307 ASSERT(m_originDocument->readyState() != "loading"); | 231 ASSERT(m_originDocument->readyState() != "loading"); |
308 if (m_domEnabled) { | 232 if (m_domEnabled) { |
309 Timeline timeline(m_originDocument->frame(), String("notifyDebugServer@")
+ m_libraryUrl); | 233 Timeline timeline(m_originDocument->frame(), String("notifyDebugServer@")
+ m_libraryUrl); |
310 DartDebugServer::shared().isolateLoaded(); | 234 DartDebugServer::shared().isolateLoaded(); |
311 } | 235 } |
| 236 |
| 237 // FIXME: Do we still need this? |
312 if (m_scriptHasError) { | 238 if (m_scriptHasError) { |
313 // Errors have already been printed to console. | 239 // Errors have already been printed to console. |
314 return; | 240 return; |
315 } | 241 } |
316 | 242 |
317 if (m_applicationLoadedCallback) | |
318 m_applicationLoadedCallback->handleEvent(); | |
319 | |
320 if (m_domEnabled) { | 243 if (m_domEnabled) { |
321 V8Scope v8scope; | 244 V8Scope v8scope; |
322 Dart_Handle result = Dart_Invoke(topLevelLibrary(), Dart_NewStringFromCS
tring("main"), 0, 0); | 245 Dart_Handle result = Dart_Invoke(topLevelLibrary(), Dart_NewStringFromCS
tring("main"), 0, 0); |
323 if (Dart_IsError(result)) | 246 if (Dart_IsError(result)) |
324 DartUtilities::reportProblem(m_originDocument, result, m_libraryUrl)
; | 247 DartUtilities::reportProblem(m_originDocument, result, m_libraryUrl)
; |
325 } | 248 } |
326 | 249 |
327 // Application loading is finished. Delete application loader for current is
olate. | 250 // Application loading is finished. Delete application loader for current is
olate. |
328 DartDOMData::current()->setApplicationLoader(0); | 251 DartDOMData::current()->setApplicationLoader(0); |
329 } | 252 } |
330 | 253 |
331 Dart_Handle DartApplicationLoader::topLevelLibrary() | 254 Dart_Handle DartApplicationLoader::topLevelLibrary() |
332 { | 255 { |
333 Dart_Handle library = Dart_LookupLibrary(DartUtilities::stringToDartString(m
_libraryUrl)); | 256 Dart_Handle library = Dart_LookupLibrary(DartUtilities::stringToDartString(m
_libraryUrl)); |
334 ASSERT(!Dart_IsError(library)); | 257 ASSERT(!Dart_IsError(library)); |
335 return library; | 258 return library; |
336 } | 259 } |
337 | 260 |
338 class ScriptLoadCallback : public ResourceClient { | |
339 public: | |
340 ScriptLoadCallback(String url, PassRefPtr<DartApplicationLoader> loader, Res
ourcePtr<ScriptResource> scriptResource) | |
341 : m_url(url) | |
342 , m_loader(loader) | |
343 , m_scriptResource(scriptResource) | |
344 { | |
345 } | |
346 | |
347 virtual void notifyFinished(Resource* cachedResource) | |
348 { | |
349 ASSERT(cachedResource->type() == Resource::Script); | |
350 ASSERT(cachedResource == m_scriptResource.get()); | |
351 ASSERT(WTF::isMainThread()); | |
352 | |
353 if (cachedResource->errorOccurred()) | |
354 m_loader->scriptLoadError(m_url); | |
355 else if (cachedResource->wasCanceled()) { | |
356 // FIXME: shall we let VM know, so it can inform application some of
its | |
357 // resources cannot be loaded? | |
358 } else { | |
359 ScriptSourceCode sourceCode(m_scriptResource.get()); | |
360 CachedMetadata* cachedMetadata = m_scriptResource->cachedMetadata(da
rtTypeID); | |
361 if (cachedMetadata) | |
362 m_loader->loadScriptFromSnapshot(sourceCode.url(), reinterpret_c
ast<const uint8_t*>(cachedMetadata->data()), static_cast<intptr_t>(cachedMetadat
a->size())); | |
363 else { | |
364 // Use the original url associated with the Script so that | |
365 // redirects do not break the DartApplicationLoader. | |
366 // FIXME: is this the correct behavior? This functionality is | |
367 // very convenient when you want the source file to act as if | |
368 // it was from the original location but that isn't always | |
369 // what the user expects. | |
370 m_loader->load(m_url, sourceCode.source(), WTF::OrdinalNumber::f
irst()); | |
371 } | |
372 } | |
373 | |
374 m_scriptResource->removeClient(this); | |
375 delete this; | |
376 } | |
377 | |
378 private: | |
379 String m_url; | |
380 RefPtr<DartApplicationLoader> m_loader; | |
381 ResourcePtr<ScriptResource> m_scriptResource; | |
382 }; | |
383 | |
384 static String resolveUrl(String mainLibraryURL, const String& url) | |
385 { | |
386 if (!url.startsWith("package:") || url.startsWith("package://")) | |
387 return url; | |
388 | |
389 String packageRoot; | |
390 String packageUrl; | |
391 if (const char* packageRootOverride = getenv("DART_PACKAGE_ROOT")) { | |
392 // Resolve with respect to the override. Append a | |
393 // slash to ensure that resolution is against this | |
394 // path and not its parent. | |
395 packageRoot = String(packageRootOverride) + "/"; | |
396 // Strip the 'package:' prefix. | |
397 packageUrl = url.substring(8); | |
398 } else { | |
399 // Resolve with respect to the entry point's URL. Note, the | |
400 // trailing file name in the entry point URL (e.g., | |
401 // 'rootpath/mainapp.dart') is stripped by the KURL | |
402 // constructor below. | |
403 packageRoot = mainLibraryURL; | |
404 packageUrl = String("packages/") + url.substring(8); | |
405 } | |
406 return KURL(KURL(KURL(), packageRoot), packageUrl).string(); | |
407 } | |
408 | |
409 void DartApplicationLoader::loadScriptResource(const String& url) | |
410 { | |
411 // Request loading of script dependencies. | |
412 FetchRequest request(m_originDocument->completeURL(resolveUrl(mainLibraryURL
(), url)), FetchInitiatorTypeNames::document, "utf8"); | |
413 // FIXME: what about charset for this script, maybe use charset of initial s
cript tag? | |
414 ResourcePtr<ScriptResource> scriptResource = m_originDocument->fetcher()->re
questScript(request); | |
415 if (scriptResource) | |
416 scriptResource->addClient(new ScriptLoadCallback(m_originDocument->compl
eteURL(url), this, scriptResource)); | |
417 else | |
418 scriptLoadError(url); | |
419 } | |
420 | |
421 void DartApplicationLoader::scriptLoadError(String failedUrl) | 261 void DartApplicationLoader::scriptLoadError(String failedUrl) |
422 { | 262 { |
423 // FIXME: try to dig out line number, -1 for now. | 263 // FIXME: try to dig out line number, -1 for now. |
424 if (failedUrl.startsWith(String("dart:"))) { | 264 if (failedUrl.startsWith(String("dart:"))) { |
425 m_originDocument->logExceptionToConsole(String("The built-in library '")
+ failedUrl + String("' is not available on Dartium."), m_libraryUrl, -1, 0, 0)
; | 265 m_originDocument->logExceptionToConsole(String("The built-in library '")
+ failedUrl + String("' is not available on Dartium."), m_libraryUrl, -1, 0, 0)
; |
426 } else { | 266 } else { |
427 m_originDocument->logExceptionToConsole(String("Failed to load a file ")
+ failedUrl, m_libraryUrl, -1, 0, 0); | 267 m_originDocument->logExceptionToConsole(String("Failed to load a file ")
+ failedUrl, m_libraryUrl, -1, 0, 0); |
428 } | 268 } |
429 m_errorEventDispatcher->dispatchErrorEvent(); | 269 m_errorEventDispatcher->dispatchErrorEvent(); |
430 } | 270 } |
431 | 271 |
432 void DartApplicationLoader::add(UrlMultiMap& map, const String& key, const Strin
g& value) | |
433 { | |
434 // We should never have a self dependence. | |
435 ASSERT(key != value); | |
436 UrlMultiMap::iterator iter = map.find(key); | |
437 if (iter == map.end()) | |
438 iter = map.add(key, new UrlSet()).iterator; | |
439 UrlSet* set = iter->value; | |
440 set->add(value); | |
441 } | 272 } |
442 | |
443 } | |
OLD | NEW |