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

Unified Diff: sdk/lib/_internal/lib/js_helper.dart

Issue 232563006: Insert checks before deferred calls and accesses. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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 side-by-side diff with in-line comments
Download patch
Index: sdk/lib/_internal/lib/js_helper.dart
diff --git a/sdk/lib/_internal/lib/js_helper.dart b/sdk/lib/_internal/lib/js_helper.dart
index e0540978ba967f409037774ea3eeeaa26c80fd10..99b25847269c122784553a1efac8c19efd0131a3 100644
--- a/sdk/lib/_internal/lib/js_helper.dart
+++ b/sdk/lib/_internal/lib/js_helper.dart
@@ -2723,6 +2723,13 @@ checkMalformedType(value, message) {
throw new TypeErrorImplementation.fromMessage(message);
}
+@NoInline()
+void checkDeferredIsLoaded(String loadId, String uri) {
+ if (!_loadedLibraries.contains(loadId)) {
+ throw new DeferredNotLoadedError(uri);
+ }
+}
+
/**
* Special interface recognized by the compiler and implemented by DOM
* objects that support integer indexing. This interface is not
@@ -2815,6 +2822,16 @@ class RuntimeError extends Error {
String toString() => "RuntimeError: $message";
}
+class DeferredNotLoadedError extends Error {
+ String libraryName;
+
+ DeferredNotLoadedError(this.libraryName);
+
+ String toString() {
+ return "Deferred library $libraryName was not loaded.";
+ }
+}
+
abstract class RuntimeType {
const RuntimeType();
@@ -3228,10 +3245,10 @@ LoadLibraryFunctionType _loadLibraryWrapper(String loadId) {
return () => loadDeferredLibrary(loadId);
}
-final Map<String, Future<Null>> _loadedLibraries = <String, Future<Null>>{};
-
-Future<bool> loadDeferredLibrary(String loadId, [String uri]) {
+final Map<String, Future<Null>> _loadingLibraries = <String, Future<Null>>{};
+final Set<String> _loadedLibraries = new Set<String>();
+Future<Null> loadDeferredLibrary(String loadId, [String uri]) {
List<List<String>> hunkLists = JS('JSExtendableArray|Null',
'\$.libraries_to_load[#]', loadId);
if (hunkLists == null) return new Future.value(null);
@@ -3240,14 +3257,14 @@ Future<bool> loadDeferredLibrary(String loadId, [String uri]) {
Iterable<Future<Null>> allLoads =
hunkNames.map((hunkName) => _loadHunk(hunkName, uri));
return Future.wait(allLoads).then((_) => null);
- });
+ }).then((_) => _loadedLibraries.add(loadId));
}
Future<Null> _loadHunk(String hunkName, String uri) {
// TODO(ahe): Validate libraryName. Kasper points out that you want
// to be able to experiment with the effect of toggling @DeferLoad,
// so perhaps we should silently ignore "bad" library names.
- Future<Null> future = _loadedLibraries[hunkName];
+ Future<Null> future = _loadingLibraries[hunkName];
if (future != null) {
return future.then((_) => null);
}
@@ -3261,7 +3278,7 @@ Future<Null> _loadHunk(String hunkName, String uri) {
if (Primitives.isJsshell || Primitives.isD8) {
// TODO(ahe): Move this code to a JavaScript command helper script that is
// not included in generated output.
- return _loadedLibraries[hunkName] = new Future<Null>(() {
+ return _loadingLibraries[hunkName] = new Future<Null>(() {
try {
// Create a new function to avoid getting access to current function
// context.
@@ -3273,7 +3290,7 @@ Future<Null> _loadHunk(String hunkName, String uri) {
});
} else if (isWorker()) {
// We are in a web worker. Load the code with an XMLHttpRequest.
- return _loadedLibraries[hunkName] = new Future<Null>(() {
+ return _loadingLibraries[hunkName] = new Future<Null>(() {
Completer completer = new Completer<Null>();
enterJsAsync();
Future<Null> leavingFuture = completer.future.whenComplete(() {
@@ -3315,7 +3332,7 @@ Future<Null> _loadHunk(String hunkName, String uri) {
});
}
// We are in a dom-context.
- return _loadedLibraries[hunkName] = new Future<Null>(() {
+ return _loadingLibraries[hunkName] = new Future<Null>(() {
Completer completer = new Completer<Null>();
// Inject a script tag.
var script = JS('', 'document.createElement("script")');

Powered by Google App Engine
This is Rietveld 408576698