mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:16:51 +00:00
Fix deferred loading with multiple apps on same page.
Even though two apps don't have to load a file twice, they still both have to initialize it. Still missing this support for the new emitter. BUG= R=floitsch@google.com Review URL: https://codereview.chromium.org//837903002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@42660 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
34a556e5a9
commit
0df0c89ae6
|
@ -15,6 +15,7 @@ import 'package:_internal/compiler/js_lib/shared/embedded_names.dart' show
|
|||
DEFERRED_LIBRARY_URIS,
|
||||
DEFERRED_LIBRARY_HASHES,
|
||||
INITIALIZE_LOADED_HUNK,
|
||||
IS_HUNK_INITIALIZED,
|
||||
IS_HUNK_LOADED;
|
||||
|
||||
import '../js_emitter.dart' show NativeGenerator;
|
||||
|
|
|
@ -161,6 +161,7 @@ class OldEmitter implements Emitter {
|
|||
String get lazyInitializerName
|
||||
=> '${namer.isolateName}.${lazyInitializerProperty}';
|
||||
String get initName => 'init';
|
||||
|
||||
String get makeConstListProperty
|
||||
=> namer.getMappedInstanceName('makeConstantList');
|
||||
|
||||
|
@ -1831,23 +1832,34 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
|
|||
/// Emits support-code for deferred loading into [buffer].
|
||||
void emitDeferredBoilerPlate(CodeBuffer buffer,
|
||||
Map<OutputUnit, String> deferredLoadHashes) {
|
||||
jsAst.Statement functions = js.statement('''
|
||||
{
|
||||
// Function for checking if a hunk is loaded given its hash.
|
||||
buffer.write(jsAst.prettyPrint(
|
||||
js('# = function(hunkHash) {'
|
||||
' return !!$deferredInitializers[hunkHash];'
|
||||
'}', generateEmbeddedGlobalAccess(embeddedNames.IS_HUNK_LOADED)),
|
||||
compiler, monitor: compiler.dumpInfoTask));
|
||||
buffer.write('$N');
|
||||
#isHunkLoaded = function(hunkHash) {
|
||||
return !!$deferredInitializers[hunkHash];
|
||||
};
|
||||
#deferredInitialized = new Object(null);
|
||||
// Function for checking if a hunk is initialized given its hash.
|
||||
#isHunkInitialized = function(hunkHash) {
|
||||
return #deferredInitialized[hunkHash];
|
||||
};
|
||||
// Function for initializing a loaded hunk, given its hash.
|
||||
buffer.write(jsAst.prettyPrint(
|
||||
js('# = function(hunkHash) {'
|
||||
' $deferredInitializers[hunkHash]('
|
||||
'$globalsHolder, ${namer.currentIsolate})'
|
||||
'}',
|
||||
generateEmbeddedGlobalAccess(
|
||||
embeddedNames.INITIALIZE_LOADED_HUNK)),
|
||||
#initializeLoadedHunk = function(hunkHash) {
|
||||
$deferredInitializers[hunkHash](
|
||||
$globalsHolder, ${namer.currentIsolate});
|
||||
#deferredInitialized[hunkHash] = true;
|
||||
};
|
||||
}
|
||||
''', {"isHunkLoaded": generateEmbeddedGlobalAccess(
|
||||
embeddedNames.IS_HUNK_LOADED),
|
||||
"isHunkInitialized": generateEmbeddedGlobalAccess(
|
||||
embeddedNames.IS_HUNK_INITIALIZED),
|
||||
"initializeLoadedHunk": generateEmbeddedGlobalAccess(
|
||||
embeddedNames.INITIALIZE_LOADED_HUNK),
|
||||
"deferredInitialized": generateEmbeddedGlobalAccess(
|
||||
embeddedNames.DEFERRED_INITIALIZED)});
|
||||
buffer.write(jsAst.prettyPrint(functions,
|
||||
compiler, monitor: compiler.dumpInfoTask));
|
||||
buffer.write('$N');
|
||||
// Write a javascript mapping from Deferred import load ids (derrived
|
||||
// from the import prefix.) to a list of lists of uris of hunks to load,
|
||||
// and a corresponding mapping to a list of hashes used by
|
||||
|
|
|
@ -15,6 +15,7 @@ import 'dart:_js_embedded_names' show
|
|||
DEFERRED_LIBRARY_HASHES,
|
||||
INITIALIZE_LOADED_HUNK,
|
||||
IS_HUNK_LOADED,
|
||||
IS_HUNK_INITIALIZED,
|
||||
NATIVE_SUPERCLASS_TAG_NAME;
|
||||
|
||||
import 'dart:collection';
|
||||
|
@ -3313,15 +3314,18 @@ Future<Null> loadDeferredLibrary(String loadId) {
|
|||
// The indices into `uris` and `hashes` that we want to load.
|
||||
List<int> indices = new List.generate(uris.length, (i) => i);
|
||||
var isHunkLoaded = JS_EMBEDDED_GLOBAL('', IS_HUNK_LOADED);
|
||||
var isHunkInitialized = JS_EMBEDDED_GLOBAL('', IS_HUNK_INITIALIZED);
|
||||
// Filter away indices for hunks that have already been loaded.
|
||||
List<int> indicesToLoad = indices
|
||||
.where((int i) => !JS('bool','#(#)', isHunkLoaded, hashes[i]))
|
||||
.toList();
|
||||
// Load the needed hunks.
|
||||
List<int> indicesToInitialize = indices
|
||||
.where((int i) => !JS('bool','#(#)', isHunkInitialized, hashes[i]))
|
||||
.toList(); // Load the needed hunks.
|
||||
return Future.wait(indicesToLoad
|
||||
.map((int i) => _loadHunk(uris[i]))).then((_) {
|
||||
// Now all hunks have been loaded, we run the needed initializers.
|
||||
for (int i in indicesToLoad) {
|
||||
for (int i in indicesToInitialize) {
|
||||
var initializer = JS_EMBEDDED_GLOBAL('', INITIALIZE_LOADED_HUNK);
|
||||
JS('void', '#(#)', initializer, hashes[i]);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,8 @@ const DEFERRED_LIBRARY_URIS = 'deferredLibraryUris';
|
|||
const DEFERRED_LIBRARY_HASHES = 'deferredLibraryHashes';
|
||||
const INITIALIZE_LOADED_HUNK = 'initializeLoadedHunk';
|
||||
const IS_HUNK_LOADED = 'isHunkLoaded';
|
||||
const IS_HUNK_INITIALIZED = 'isHunkInitialized';
|
||||
const DEFERRED_INITIALIZED = 'deferredInitialized';
|
||||
const CLASS_ID_EXTRACTOR = 'classIdExtractor';
|
||||
const CLASS_FIELDS_EXTRACTOR = 'classFieldsExtractor';
|
||||
const INSTANCE_FROM_CLASS_ID = "instanceFromClassId";
|
||||
|
|
28
tests/html/deferred_multi_app.dart
Normal file
28
tests/html/deferred_multi_app.dart
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import "deferred_multi_app_lib.dart" deferred as lib;
|
||||
import "dart:async";
|
||||
import "dart:html";
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
main() {
|
||||
Element state = querySelector("#state");
|
||||
if (state.text == "1") {
|
||||
lib.loadLibrary().then((_) {
|
||||
var a = lib.one();
|
||||
Expect.equals("one", a);
|
||||
window.postMessage(a, '*');
|
||||
});
|
||||
state.text = "2";
|
||||
} else {
|
||||
new Timer(new Duration(milliseconds: 100), () {
|
||||
lib.loadLibrary().then((_) {
|
||||
var a = lib.two();
|
||||
Expect.equals("two", a);
|
||||
window.postMessage(a, '*');
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
23
tests/html/deferred_multi_app_htmltest.html
Normal file
23
tests/html/deferred_multi_app_htmltest.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!--
|
||||
Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
||||
for details. All rights reserved. Use of this source code is governed by a
|
||||
BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
Test that two instances of a script does not interfere when loading the same
|
||||
deferred library.
|
||||
|
||||
START_HTML_DART_TEST
|
||||
{
|
||||
"scripts": ["deferred_multi_app.dart"],
|
||||
"expectedMessages": ["one", "two"]
|
||||
}
|
||||
END_HTML_DART_TEST
|
||||
-->
|
||||
<html>
|
||||
<body>
|
||||
<div id="state">1</div>
|
||||
<script>window.parent.dispatchEvent(new Event('detect_errors'));</script>
|
||||
<script src="deferred_multi_app.dart" type="application/dart"></script>
|
||||
<script src="deferred_multi_app.dart" type="application/dart"></script>
|
||||
</body>
|
||||
</html>
|
11
tests/html/deferred_multi_app_lib.dart
Normal file
11
tests/html/deferred_multi_app_lib.dart
Normal file
|
@ -0,0 +1,11 @@
|
|||
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
one() {
|
||||
return "one";
|
||||
}
|
||||
|
||||
two() {
|
||||
return "two";
|
||||
}
|
|
@ -105,6 +105,9 @@ xhr_test: Pass, Fail # Issue 11884
|
|||
[$runtime == drt || $runtime == dartium || $runtime == chrome || $runtime == chromeOnAndroid || $runtime == ContentShellOnAndroid ]
|
||||
webgl_1_test: Pass, Fail # Issue 8219
|
||||
|
||||
[ ($compiler == none || $compiler == dart2dart) ]
|
||||
deferred_multi_app_htmltest: Fail # Issue 16603
|
||||
|
||||
[ $compiler == none && ($runtime == drt || $runtime == dartium) && $system == windows]
|
||||
websql_test: Skip # Issue 4941: stderr contains a backtrace.
|
||||
|
||||
|
|
Loading…
Reference in a new issue