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

Side by Side Diff: sky/engine/bindings-dart/core/dart/DartApplicationLoader.cpp

Issue 918273002: Remove bindings-dart (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 10 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
OLDNEW
(Empty)
1 // Copyright (c) 2009, 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/core/dart/DartApplicationLoader.h"
32
33 #include "core/FetchInitiatorTypeNames.h"
34 #include "bindings/core/dart/DartDOMWrapper.h"
35 #include "bindings/core/dart/DartInspectorTimeline.h"
36 #include "bindings/core/dart/DartScriptDebugServer.h"
37 #include "bindings/core/dart/DartUtilities.h"
38 #if defined(ENABLE_DART_NATIVE_EXTENSIONS)
39 #include "bindings/core/dart/shared_lib/DartNativeExtensions.h"
40 #endif
41 #include "bindings/core/v8/ScriptSourceCode.h"
42 #include "core/dom/Document.h"
43 #include "core/dom/Element.h"
44 #include "core/dom/ScriptLoader.h"
45 #include "core/dom/ScriptLoaderClient.h"
46 #include "core/fetch/CachedMetadata.h"
47 #include "core/fetch/FetchRequest.h"
48 #include "core/fetch/ResourceClient.h"
49 #include "core/fetch/ResourceFetcher.h"
50 #include "core/fetch/ScriptResource.h"
51 #include "core/frame/LocalDOMWindow.h"
52 #include "core/frame/LocalFrame.h"
53 #include "core/html/HTMLScriptElement.h"
54 #include "core/inspector/ScriptCallStack.h"
55 #include "core/svg/SVGScriptElement.h"
56
57 #include <dart_api.h>
58 #include <dart_mirrors_api.h>
59
60 namespace blink {
61
62 // FIXME(vsm): Define this in a central place.
63 static const unsigned dartTypeID = 0xDAADDAAD;
64
65 PassRefPtr<DartScriptInfo> DartScriptInfo::create(PassRefPtr<Element> scriptElem ent)
66 {
67 RefPtr<DartScriptInfo> scriptInfo = adoptRef(new DartScriptInfo(scriptElemen t));
68 if (scriptInfo->loader())
69 return scriptInfo;
70 return nullptr;
71 }
72
73 String DartScriptInfo::sourceAttributeValue() const
74 {
75 return m_client->sourceAttributeValue();
76 }
77
78 String DartScriptInfo::typeAttributeValue() const
79 {
80 return m_client->typeAttributeValue();
81 }
82
83 String DartScriptInfo::scriptContent()
84 {
85 return m_loader->scriptContent();
86 }
87
88 void DartScriptInfo::dispatchErrorEvent()
89 {
90 m_loader->dispatchErrorEvent();
91 }
92
93 WTF::OrdinalNumber DartScriptInfo::startLineNumber()
94 {
95 return m_loader->startLineNumber();
96 }
97
98 ScriptLoader* DartScriptInfo::loader()
99 {
100 return m_loader;
101 }
102
103 Document* DartScriptInfo::ownerDocument()
104 {
105 return m_element->ownerDocument();
106 }
107
108 String DartScriptInfo::url()
109 {
110 String scriptURL = sourceAttributeValue();
111 KURL ownerURL = ownerDocument()->url();
112 return scriptURL.isEmpty() ? ownerURL : KURL(ownerURL, scriptURL);
113 }
114
115 DartScriptInfo::DartScriptInfo(PassRefPtr<Element> element)
116 {
117 m_element = element;
118 if (m_element->document().isHTMLDocument()) {
119 HTMLScriptElement* scriptElement = static_cast<HTMLScriptElement*>(m_ele ment.get());
120 m_loader = scriptElement->loader();
121 m_client = static_cast<ScriptLoaderClient*>(scriptElement);
122 } else if (m_element->document().isSVGDocument()) {
123 SVGScriptElement* scriptElement = static_cast<SVGScriptElement*>(m_eleme nt.get());
124 m_loader = scriptElement->loader();
125 m_client = static_cast<ScriptLoaderClient*>(scriptElement);
126 } else {
127 // Invalid script element.
128 m_loader = 0;
129 m_client = 0;
130 m_element = nullptr;
131 }
132 }
133
134 void DartApplicationLoader::Callback::reportError(const String& error, const Str ing& url)
135 {
136 m_originDocument->logExceptionToConsole(error + ": " + url, url, 0, 0, nullp tr);
137 if (m_scriptInfo)
138 m_scriptInfo->loader()->dispatchErrorEvent();
139 }
140
141 ResourcePtr<ScriptResource> DartApplicationLoader::Callback::requestScript(Fetch Request& request)
142 {
143 return m_originDocument->fetcher()->fetchScript(request);
144 }
145
146 Document* DartApplicationLoader::Callback::document()
147 {
148 return m_scriptInfo ? m_scriptInfo->ownerDocument() : m_originDocument;
149 }
150
151 DartApplicationLoader::DartApplicationLoader(
152 Document* document,
153 bool domEnabled)
154 : m_isolate(0)
155 , m_originDocument(document)
156 , m_loadCallback(nullptr)
157 , m_domEnabled(domEnabled)
158 , m_cacheable(false)
159 , m_state(Uninitialized)
160 , m_snapshotMode(SnapshotOff)
161 {
162 ASSERT(m_originDocument);
163
164 DEFINE_STATIC_LOCAL(String, setting, (getenv("DART_SNAPSHOT_MODE")));
165 if (!setting.isNull()) {
166 if (setting == "all")
167 m_snapshotMode = SnapshotAll;
168 else if (setting == "off")
169 m_snapshotMode = SnapshotOff;
170 else if (setting == "single")
171 m_snapshotMode = SnapshotSingle;
172 else
173 DartUtilities::reportProblem(m_originDocument, String("Invalid DART_ SNAPSHOT_MODE: ") + setting);
174 }
175 }
176
177 void DartApplicationLoader::addRequest(PassRefPtr<DartScriptInfo> scriptInfo)
178 {
179 // FIXME(vsm): Temporary support to load extra Dart libraries via HTML impor ts before we encounter the main
180 // script. In the future, this should map to deferred loading.
181 RELEASE_ASSERT(m_state == Uninitialized);
182 m_htmlImportedScripts.append(scriptInfo);
183 }
184
185 void DartApplicationLoader::initialize(Dart_Isolate isolate, const String& scrip tUrl, PassRefPtr<Callback> loadCallback)
186 {
187 RELEASE_ASSERT(m_state == Uninitialized && !m_isolate);
188 m_isolate = isolate;
189 m_loadCallback = loadCallback;
190
191 Document* document = m_loadCallback->document();
192 m_scriptUrl = KURL(document->baseURL(), scriptUrl);
193 m_scriptUrlString = m_scriptUrl.string();
194
195 RELEASE_ASSERT(m_isolate == isolate);
196 Dart_EnterIsolate(isolate);
197
198 // Associate application loader with current isolate, so we can retrieve it in libraryTagHandlerCallback.
199 DartDOMData::current()->setApplicationLoader(this);
200 Dart_Handle ALLOW_UNUSED result = Dart_SetLibraryTagHandler(&libraryTagHandl erCallback);
201 ASSERT(!Dart_IsError(result));
202
203 // FIXME: Stay in isolate for processing below.
204 Dart_ExitIsolate();
205 m_state = Initialized;
206 }
207
208 void DartApplicationLoader::processRequests(Dart_Isolate isolate, const ScriptSo urceCode& sourceCode, PassRefPtr<Callback> loadCallback)
209 {
210 DART_START_TIMER();
211 const String& scriptUrl = sourceCode.url();
212 initialize(isolate, scriptUrl, loadCallback);
213 DART_RECORD_TIMER(" DartApplicationLoader::initialize took");
214
215 m_state = Fetching;
216
217 // Check for cached snapshot.
218 ScriptResource* scriptResource = sourceCode.resource();
219 if (scriptResource && m_snapshotMode != SnapshotOff) {
220 // This is cacheable if there is a resource we can cache the snapshot on .
221 m_cacheable = true;
222 CachedMetadata* cachedMetadata = scriptResource->cachedMetadata(dartType ID);
223 if (cachedMetadata) {
224 loadScriptFromSnapshot(sourceCode.url(), reinterpret_cast<const uint 8_t*>(cachedMetadata->data()), cachedMetadata->size());
225 return;
226 }
227 }
228
229 // Set up root library for main DOM isolate.
230 {
231 DartIsolateScope isolateScope(m_isolate);
232 DartApiScope apiScope;
233
234 ASSERT(Dart_IsNull(Dart_RootLibrary()));
235
236 Document* document = m_loadCallback->document();
237 const String& source = sourceCode.source();
238 int lineNumber = sourceCode.startLine();
239
240 // Use zero-based counting instead of one-based.
241 lineNumber = (lineNumber <= 0) ? 0 : lineNumber - 1;
242
243 String canonical = KURL(document->url(), scriptUrl).string();
244 m_pendingLibraries.add(canonical);
245 process(canonical, source, lineNumber);
246 RELEASE_ASSERT(m_state >= Loading);
247 }
248
249 // FIXME(vsm): This will go away.
250 // Load HTML imported dart scripts.
251 while (!m_htmlImportedScripts.isEmpty()) {
252 RefPtr<DartScriptInfo> script = m_htmlImportedScripts.takeFirst();
253 const String& src = script->sourceAttributeValue();
254 const String& url = script->url();
255 if (src.isEmpty()) {
256 // Inline script.
257 ASSERT(!m_pendingLibraries.contains(url));
258 m_pendingLibraries.add(url);
259 intptr_t lineOffset = script->startLineNumber().zeroBasedInt();
260 // Blink gives generated script tags an invalid start line.
261 if (lineOffset < 0)
262 lineOffset = 0;
263 process(script->url(), script->scriptContent(), lineOffset);
264 } else {
265 // Canonicalize the src attribute url.
266 String canonical = KURL(script->ownerDocument()->url(), src).string( );
267
268 // Check if this was loaded by an earlier script.
269 {
270 DartIsolateScope isolateScope(m_isolate);
271 DartApiScope apiScope;
272 Dart_Handle library = Dart_LookupLibrary(DartUtilities::safeStri ngToDartString(canonical));
273 if (!Dart_IsError(library))
274 continue;
275 }
276
277 // Request if we don't have the script or haven't already requested it.
278 if (!m_pendingLibraries.contains(canonical)) {
279 m_pendingLibraries.add(canonical);
280 fetchScriptResource(canonical);
281 }
282 }
283 }
284
285 // FIXME(vsm): Once m_htmlImportedScripts goes away, we should be able to de lete this.
286 // Processing HTML imports may be made the app ready without running.
287 RELEASE_ASSERT(m_state == Error || m_state >= Loading);
288 if (ready() && m_state == Loading) {
289 m_state = Ready;
290 // All dependences are in.
291 m_loadCallback->ready();
292 }
293
294 DART_RECORD_TIMER(" DartApplicationLoader::processRequests took");
295 }
296
297 void DartApplicationLoader::processSingleRequest(Dart_Isolate isolate, const Str ing& scriptUrl, PassRefPtr<Callback> loadCallback)
298 {
299 initialize(isolate, scriptUrl, loadCallback);
300 m_pendingLibraries.add(scriptUrl);
301 m_state = Fetching;
302 fetchScriptResource(scriptUrl);
303 }
304
305 void DartApplicationLoader::load(PassRefPtr<DartErrorEventDispatcher> errorEvent Dispatcher)
306 {
307 RELEASE_ASSERT(m_state == Ready || m_state == DeferredReady);
308
309 m_errorEventDispatcher = errorEventDispatcher;
310
311 DartIsolateScope isolateScope(m_isolate);
312 DartApiScope dartApiScope;
313 bool completeFutures = false;
314
315 // Finalize classes and complete futures if there are any deferred loads.
316 if (m_state == DeferredReady) {
317 // We have already invoked the entry point on the main script URL at
318 // this point we will start running dart code again.
319 m_state = Running;
320 completeFutures = true;
321 } else {
322 RELEASE_ASSERT(m_state == Ready);
323 }
324
325 {
326 V8Scope v8scope(DartDOMData::current());
327 Dart_Handle result = Dart_FinalizeLoading(completeFutures);
328 if (Dart_IsError(result)) {
329 reportDartError(result);
330 return;
331 }
332 }
333 // Invoke the entry point on the main script URL if it has not yet been
334 // invoked.
335 if (m_state == Ready) {
336 // Call the entry point on the main script URL.
337 callEntryPoint();
338 }
339 }
340
341 void DartApplicationLoader::loadScriptFromSnapshot(const String& url, const uint 8_t* snapshot, intptr_t snapshotSize)
342 {
343 DART_START_TIMER();
344 RELEASE_ASSERT(m_state == Fetching);
345
346 Timeline timeline(m_originDocument->frame(), String("loadSnapshot@") + m_scr iptUrlString);
347 m_scriptUrlString = url;
348 DartIsolateScope isolateScope(m_isolate);
349 DartApiScope apiScope;
350 Dart_Handle result = Dart_LoadScriptFromSnapshot(snapshot, snapshotSize);
351 if (Dart_IsError(result)) {
352 reportDartError(result);
353 return;
354 }
355
356 m_state = Ready;
357 m_loadCallback->ready();
358 DART_RECORD_TIMER(" DartApplicationLoader::loadScriptFromSnapshot took");
359 }
360
361 void DartApplicationLoader::callEntryPoint()
362 {
363 RELEASE_ASSERT(m_state == Ready);
364
365 Timeline timeline(m_originDocument->frame(), String("callEntryPoint@") + m_s criptUrlString);
366
367 if (m_cacheable) {
368 // Snapshot single-script applications.
369 ResourceFetcher* loader = m_originDocument->fetcher();
370 FetchRequest request(m_originDocument->completeURL(m_scriptUrlString), F etchInitiatorTypeNames::document);
371 ResourcePtr<ScriptResource> scriptResource = loader->fetchScript(request );
372
373 // Check if already snapshotted.
374 if (scriptResource && !scriptResource->cachedMetadata(dartTypeID)) {
375 uint8_t* buffer;
376 intptr_t size;
377 Dart_Handle result = Dart_CreateScriptSnapshot(&buffer, &size);
378 if (Dart_IsError(result)) {
379 reportDartError(result);
380 // FIXME: exiting early might be not the best option if error is due to snapshot
381 // creation proper (and not due to compilation), even though it' s unlikely.
382 // Consider other options like Dart_CompileAll.
383 return;
384 }
385
386 Vector<uint8_t>* snapshot = DartDOMData::current()->applicationSnaps hot();
387 ASSERT(snapshot->isEmpty());
388 snapshot->append(buffer, size);
389
390 // Write the snapshot.
391 scriptResource->setCachedMetadata(dartTypeID, reinterpret_cast<const char*>(buffer), size);
392 }
393 }
394
395 if (m_domEnabled) {
396 Timeline timeline(m_originDocument->frame(), String("notifyDebugServer@" ) + m_scriptUrlString);
397 DartScriptDebugServer::shared().isolateLoaded();
398 }
399
400 m_state = Running;
401 if (m_domEnabled) {
402 V8Scope v8scope(DartDOMData::current());
403 Dart_Handle mainLibrary = topLevelLibrary();
404
405 // Trampoline to invoke main.
406 // FIXME: Use the page library instead. To do this, we need to import ea ch script tag's library into the page
407 // with a unique prefix to ensure a secondary script doesn't define a ma in.
408 String trampolineUrl = m_scriptUrlString + "$trampoline";
409 Dart_Handle trampoline = Dart_LoadLibrary(DartUtilities::safeStringToDar tString(trampolineUrl), Dart_NewStringFromCString(""), 0, 0);
410 Dart_LibraryImportLibrary(trampoline, mainLibrary, Dart_Null());
411
412 Dart_Handle result = Dart_FinalizeLoading(false);
413 if (Dart_IsError(result)) {
414 DartUtilities::reportProblem(m_originDocument, result, m_scriptUrlSt ring);
415 }
416
417 // FIXME: Settle on proper behavior here. We have not determined exactly when
418 // or how often we'll call the entry point.
419 Dart_Handle entryPoint = Dart_NewStringFromCString("main");
420 Dart_Handle main = Dart_LookupFunction(trampoline, entryPoint);
421 if (!Dart_IsNull(main)) {
422 // FIXME: Avoid relooking up main.
423 Dart_Handle result = Dart_Invoke(trampoline, entryPoint, 0, 0);
424 if (Dart_IsError(result)) {
425 DartUtilities::reportProblem(m_originDocument, result, m_scriptU rlString);
426 }
427 }
428 }
429 }
430
431 void DartApplicationLoader::validateUrlLoaded(const String& url)
432 {
433 RELEASE_ASSERT(m_state == Running);
434
435 DartIsolateScope isolateScope(m_isolate);
436 DartApiScope apiScope;
437
438 Dart_Handle library = Dart_LookupLibrary(DartUtilities::safeStringToDartStri ng(url));
439 if (!Dart_IsNull(library)) {
440 DartUtilities::reportProblem(m_originDocument, "URL must be imported by main Dart script: " + url);
441 }
442 }
443
444 Dart_Handle DartApplicationLoader::topLevelLibrary()
445 {
446 Dart_Handle library = Dart_LookupLibrary(DartUtilities::safeStringToDartStri ng(m_scriptUrlString));
447 ASSERT(!Dart_IsError(library));
448 return library;
449 }
450
451 void DartApplicationLoader::findDependences(const String& url, const String& sou rce, intptr_t lineNumber)
452 {
453 ASSERT(m_pendingLibraries.contains(url) || m_pendingSource.contains(url));
454
455 DartIsolateScope isolateScope(m_isolate);
456 DartApiScope dartApiScope;
457
458 if (m_pendingLibraries.contains(url)) {
459 processLibrary(url, source, lineNumber);
460 } else {
461 ASSERT(m_pendingSource.contains(url));
462 processSource(url, source, lineNumber);
463 }
464 }
465
466 void DartApplicationLoader::processLibrary(const String& url, const String& sour ce, intptr_t lineNumber)
467 {
468 ASSERT(m_pendingLibraries.contains(url));
469
470 Dart_Handle result;
471 if (m_state == Fetching) {
472 // A spawned isolate.
473 m_state = Loading;
474 result = Dart_LoadScript(DartUtilities::safeStringToDartString(url), Dar tUtilities::convertSourceString(source), lineNumber, 0);
475 } else {
476 result = Dart_LoadLibrary(DartUtilities::safeStringToDartString(url), Da rtUtilities::convertSourceString(source), lineNumber, 0);
477 }
478 if (Dart_IsError(result))
479 reportError(result, url);
480
481 m_pendingLibraries.remove(url);
482 }
483
484 void DartApplicationLoader::processSource(const String& url, const String& sourc e, intptr_t lineNumber)
485 {
486 ASSERT(m_pendingSource.contains(url));
487 HandleSet* importers = m_pendingSource.take(url);
488 for (HandleSet::iterator i = importers->begin(); i != importers->end(); ++i) {
489 Dart_Handle persistent = *i;
490 Dart_Handle library = Dart_HandleFromPersistent(persistent);
491 Dart_DeletePersistentHandle(persistent);
492
493 Dart_Handle result = Dart_LoadSource(library, DartUtilities::safeStringT oDartString(url), DartUtilities::convertSourceString(source), lineNumber, 0);
494 if (Dart_IsError(result))
495 reportError(result, url);
496 }
497 delete importers;
498 }
499
500 void DartApplicationLoader::process(const String& url, const String& source, int ptr_t lineNumber)
501 {
502 if (m_state == Error)
503 return;
504
505 if (url != m_scriptUrlString && m_snapshotMode != SnapshotAll)
506 m_cacheable = false;
507
508 RELEASE_ASSERT(m_state == Fetching || m_state == Loading || m_state == Defer redLoading);
509 findDependences(url, source, lineNumber);
510 RELEASE_ASSERT(m_state == Error || m_state == Loading || m_state == Deferred Loading);
511
512 if (ready()) {
513 m_state = (m_state == Loading) ? Ready : DeferredReady;
514 // All dependences are in.
515 m_loadCallback->ready();
516 }
517 }
518
519 Dart_Handle DartApplicationLoader::libraryTagHandlerCallback(Dart_LibraryTag tag , Dart_Handle library, Dart_Handle urlHandle)
520 {
521 ASSERT(Dart_CurrentIsolate());
522 ASSERT(Dart_IsLibrary(library));
523
524 const String url = DartUtilities::toString(urlHandle);
525
526 if (tag == Dart_kCanonicalizeUrl) {
527 // If a dart application calls spawnUri, the DartVM will call this
528 // libraryTagHandler to canonicalize the url.
529 // DartDOMData::current()->scriptLoader() may be 0 at this point.
530 return DartUtilities::canonicalizeUrl(library, urlHandle, url);
531 }
532
533 if (url.startsWith("dart:")) {
534 // All supported system URLs are already built-in and shouldn't get to t his point.
535 return Dart_NewApiError("The requested built-in library is not available on Dartium.");
536 }
537
538 RefPtr<DartApplicationLoader> loader = DartDOMData::current()->applicationLo ader();
539 ASSERT(loader);
540 // We can only handle requests in one of the following states.
541 if (loader->m_state == Error)
542 return Dart_NewApiError("The isolate is in an invalid state.");
543 RELEASE_ASSERT(loader->m_state == Fetching || loader->m_state == Loading || loader->m_state == Running || loader->m_state == DeferredLoading);
544
545
546 // Fetch non-system URLs.
547 if (tag == Dart_kImportTag) {
548 if (loader->m_pendingLibraries.contains(url))
549 return Dart_True();
550 #if defined(ENABLE_DART_NATIVE_EXTENSIONS)
551 if (url.startsWith("dart-ext:")) {
552 return DartNativeExtensions::loadExtension(url, library);
553 }
554 #endif
555 loader->m_pendingLibraries.add(url);
556 } else if (tag == Dart_kSourceTag) {
557 Dart_PersistentHandle importer = Dart_NewPersistentHandle(library);
558 HandleSet* importers;
559 if (loader->m_pendingSource.contains(url)) {
560 // We have already requested this url. It is a part of more than one library.
561 importers = loader->m_pendingSource.get(url);
562 importers->append(importer);
563 return Dart_True();
564 }
565 importers = new HandleSet();
566 loader->m_pendingSource.add(url, importers);
567 importers->append(importer);
568 } else {
569 ASSERT_NOT_REACHED();
570 }
571
572 // If the isolate is running, this is part of a deferred load request.
573 if (loader->m_state == Running)
574 loader->m_state = DeferredLoading;
575 loader->fetchScriptResource(url);
576 return Dart_True();
577 }
578
579 class ScriptLoadedCallback : public ResourceClient {
580 public:
581 ScriptLoadedCallback(String url, PassRefPtr<DartApplicationLoader> loader, R esourcePtr<ScriptResource> scriptResource)
582 : m_url(url)
583 , m_loader(loader)
584 , m_scriptResource(scriptResource)
585 {
586 }
587
588 virtual void notifyFinished(Resource* cachedResource)
589 {
590 ASSERT(cachedResource->type() == Resource::Script);
591 ASSERT(cachedResource == m_scriptResource.get());
592 ASSERT(WTF::isMainThread());
593
594 if (cachedResource->errorOccurred()) {
595 m_loader->reportError(String("An error occurred loading file"), m_ur l);
596 } else if (cachedResource->wasCanceled()) {
597 // FIXME: shall we let VM know, so it can inform application some of its
598 // resources cannot be loaded?
599 m_loader->reportError(String("File request cancelled"), m_url);
600 } else {
601 ScriptSourceCode sourceCode(m_scriptResource.get());
602
603 // Use the original url associated with the Script so that
604 // redirects do not break the DartScriptLoader.
605 // FIXME: is this the correct behavior? This functionality is
606 // very convenient when you want the source file to act as if
607 // it was from the original location but that isn't always
608 // what the user expects.
609 m_loader->process(m_url, sourceCode.source(), 0);
610 }
611
612 m_scriptResource->removeClient(this);
613 delete this;
614 }
615
616 private:
617 String m_url;
618 RefPtr<DartApplicationLoader> m_loader;
619 ResourcePtr<ScriptResource> m_scriptResource;
620 };
621
622 static String resolveUrl(String mainLibraryURL, const String& url)
623 {
624 if (!url.startsWith("package:") || url.startsWith("package://"))
625 return url;
626
627 String packageRoot;
628 String packageUrl;
629 if (const char* packageRootOverride = getenv("DART_PACKAGE_ROOT")) {
630 // Resolve with respect to the override. Append a
631 // slash to ensure that resolution is against this
632 // path and not its parent.
633 packageRoot = String(packageRootOverride) + "/";
634 // Strip the 'package:' prefix.
635 packageUrl = url.substring(8);
636 } else {
637 // Resolve with respect to the entry point's URL. Note, the
638 // trailing file name in the entry point URL (e.g.,
639 // 'rootpath/mainapp.dart') is stripped by the KURL
640 // constructor below.
641 packageRoot = mainLibraryURL;
642 packageUrl = String("packages/") + url.substring(8);
643 }
644 return KURL(KURL(KURL(), packageRoot), packageUrl).string();
645 }
646
647 void DartApplicationLoader::fetchScriptResource(const String& url)
648 {
649 // Request loading of script dependencies.
650 FetchRequest request(m_loadCallback->completeURL(resolveUrl(m_scriptUrl, url )),
651 FetchInitiatorTypeNames::document, "utf8");
652 // FIXME: what about charset for this script, maybe use charset of initial s cript tag?
653 ResourcePtr<ScriptResource> scriptResource = m_loadCallback->requestScript(r equest);
654 if (scriptResource) {
655 scriptResource->addClient(new ScriptLoadedCallback(m_loadCallback->compl eteURL(url), this, scriptResource));
656 } else {
657 m_loadCallback->reportError(String("File request error"), url);
658 }
659 }
660
661 // FIXME(vsm): Merge these functions below. We need to be careful about where th e error is dispatched.
662 void DartApplicationLoader::scriptLoadError(String failedUrl)
663 {
664 if (m_state < Running)
665 m_state = Error;
666 // FIXME: try to dig out line number, -1 for now.
667 if (failedUrl.startsWith(String("dart:"))) {
668 m_originDocument->logExceptionToConsole(String("The built-in library '") + failedUrl + String("' is not available on Dartium."), m_scriptUrlString, -1, 0, nullptr);
669 } else {
670 m_originDocument->logExceptionToConsole(String("Failed to load a file ") + failedUrl, m_scriptUrlString, -1, 0, nullptr);
671 }
672 RELEASE_ASSERT(m_errorEventDispatcher);
673 m_errorEventDispatcher->dispatchErrorEvent();
674 }
675
676 void DartApplicationLoader::reportDartError(Dart_Handle error)
677 {
678 if (m_state < Running)
679 m_state = Error;
680 DartUtilities::reportProblem(m_originDocument, error, m_scriptUrlString);
681 }
682
683 void DartApplicationLoader::reportError(Dart_Handle error, const String& url)
684 {
685 reportError(Dart_GetError(error), url);
686 }
687
688 void DartApplicationLoader::reportError(const String& error, const String& url)
689 {
690 if (m_state < Running)
691 m_state = Error;
692 m_loadCallback->reportError(error, url);
693 }
694
695
696 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698