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

Unified Diff: lib/runtime/dart_runtime.js

Issue 1171843002: Load on demand (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Address comments Created 5 years, 6 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
« no previous file with comments | « no previous file | test/browser/index.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/runtime/dart_runtime.js
diff --git a/lib/runtime/dart_runtime.js b/lib/runtime/dart_runtime.js
index 8f48253d762d6cca2dd7ef5f2b5c182940d518bf..ac24ada78f9fbafa61e3bfbfc811c6a87fedef94 100644
--- a/lib/runtime/dart_runtime.js
+++ b/lib/runtime/dart_runtime.js
@@ -2,15 +2,10 @@
// 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.
-var dart, _js_helper, _js_primitives, dartx;
+var dart, dartx;
(function (dart) {
'use strict';
- // TODO(vsm): This is referenced (as init.globalState) from
- // isolate_helper.dart. Where should it go?
- // See: https://github.com/dart-lang/dev_compiler/issues/164
- dart.globalState = null;
-
const defineProperty = Object.defineProperty;
const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
const getOwnPropertyNames = Object.getOwnPropertyNames;
@@ -35,7 +30,7 @@ var dart, _js_helper, _js_primitives, dartx;
// types. hasOwnProperty doesn't chase the proto chain.
// Also, do we want an NSM on regular JS objects?
// See: https://github.com/dart-lang/dev_compiler/issues/169
- var result = obj[field];
+ let result = obj[field];
// TODO(vsm): Check this more robustly.
if (typeof result == "function" && !hasOwnProperty.call(obj, field)) {
@@ -108,7 +103,7 @@ var dart, _js_helper, _js_primitives, dartx;
let _extensionType = Symbol('extensionType');
function _canonicalFieldName(obj, name, args, displayName) {
if (obj[_extensionType]) {
- var extension = dartx[name];
+ let extension = dartx[name];
if (extension) return extension;
// TODO(jmesserly): in the future we might have types that "overlay" Dart
// methods while also exposing the full native API, e.g. dart:html vs
@@ -144,11 +139,11 @@ var dart, _js_helper, _js_primitives, dartx;
function typeToString(type) {
if (typeof(type) == "function") {
- var name = type.name;
- var args = type[dart.typeArguments];
+ let name = type.name;
+ let args = type[dart.typeArguments];
if (args) {
name += '<';
- for (var i = 0; i < args.length; ++i) {
+ for (let i = 0; i < args.length; ++i) {
if (i > 0) name += ', ';
name += typeToString(args[i]);
}
@@ -209,7 +204,7 @@ var dart, _js_helper, _js_primitives, dartx;
* Currently this will return null for non-Dart objects.
*/
function realRuntimeType(obj) {
- var result = checkPrimitiveType(obj);
+ let result = checkPrimitiveType(obj);
if (result !== null) return result;
// TODO(vsm): Should we treat Dart and JS objects differently here?
// E.g., we can check if obj instanceof core.Object to differentiate.
@@ -321,7 +316,7 @@ var dart, _js_helper, _js_primitives, dartx;
}
function safeGetOwnProperty(obj, name) {
- var desc = getOwnPropertyDescriptor(obj, name);
+ let desc = getOwnPropertyDescriptor(obj, name);
if (desc) return desc.value;
}
@@ -402,7 +397,7 @@ var dart, _js_helper, _js_primitives, dartx;
for (let i = 0; i < type.optionals.length; ++i) {
if (!_isBottom(type.optionals[i], true)) return false;
}
- var names = getOwnPropertyNames(type.named);
+ let names = getOwnPropertyNames(type.named);
for (let i = 0; i < names.length; ++i) {
if (!_isBottom(type.named[names[i]], true)) return false;
}
@@ -441,7 +436,7 @@ var dart, _js_helper, _js_primitives, dartx;
function _typeName(type) {
if (type === void 0) throwRuntimeError('Undefined type');
- var name = type.name;
+ let name = type.name;
if (!name) throwRuntimeError('Unexpected type: ' + type);
return name;
}
@@ -455,7 +450,7 @@ var dart, _js_helper, _js_primitives, dartx;
/// actuals.
checkApply(actuals) {
if (actuals.length < this.args.length) return false;
- var index = 0;
+ let index = 0;
for(let i = 0; i < this.args.length; ++i) {
if (!instanceOfOrNull(actuals[i], this.args[i])) return false;
++index;
@@ -491,7 +486,7 @@ var dart, _js_helper, _js_primitives, dartx;
get name() {
if (this._stringValue) return this._stringValue;
- var buffer = '(';
+ let buffer = '(';
for (let i = 0; i < this.args.length; ++i) {
if (i > 0) {
buffer += ', ';
@@ -550,7 +545,7 @@ var dart, _js_helper, _js_primitives, dartx;
defineLazyProperty(closure, _runtimeType, {get : arguments[1]});
return closure;
}
- var t;
+ let t;
if (arguments.length == 1) {
// No type arguments, it's all dynamic
let len = closure.length;
@@ -574,8 +569,8 @@ var dart, _js_helper, _js_primitives, dartx;
function functionType(returnType, args, extra) {
// TODO(vsm): Cache / memomize?
- var optionals;
- var named;
+ let optionals;
+ let named;
if (extra === void 0) {
optionals = [];
named = {};
@@ -638,7 +633,7 @@ var dart, _js_helper, _js_primitives, dartx;
function getFunctionType(obj) {
// TODO(vsm): Encode this properly on the function for Dart-generated code.
- var args = Array.apply(null, new Array(obj.length)).map(() => core.Object);
+ let args = Array.apply(null, new Array(obj.length)).map(() => core.Object);
return functionType(dart.bottom, args);
}
@@ -682,7 +677,7 @@ var dart, _js_helper, _js_primitives, dartx;
return false;
}
- var j = 0;
+ let j = 0;
for (let i = args1.length; i < args2.length; ++i, ++j) {
if (!isSubtype_(args2[i], optionals1[j], true)) {
return false;
@@ -839,9 +834,9 @@ var dart, _js_helper, _js_primitives, dartx;
// annotations) any time we copy a method as part of our metaprogramming.
// It might be more friendly to JS metaprogramming if we include this info
// on the function.
- var originalSigFn = getOwnPropertyDescriptor(type, _methodSig).get;
+ let originalSigFn = getOwnPropertyDescriptor(type, _methodSig).get;
defineMemoizedGetter(type, _methodSig, function() {
- var sig = originalSigFn();
+ let sig = originalSigFn();
for (let name of methodNames) {
sig[getExtensionSymbol(name)] = sig[name];
}
@@ -1148,7 +1143,7 @@ var dart, _js_helper, _js_primitives, dartx;
* returns the result. If the value is not found, [valueFn] will be called to
* add it. For example:
*
- * var map = new Map();
+ * let map = new Map();
* putIfAbsent(map, [1, 2, 'hi ', 'there '], () => 'world');
*
* ... will create a Map with a structure like:
@@ -1247,7 +1242,7 @@ var dart, _js_helper, _js_primitives, dartx;
dart.hashCode = hashCode;
function runtimeType(obj) {
- var result = checkPrimitiveType(obj);
+ let result = checkPrimitiveType(obj);
if (result !== null) return result;
return obj.runtimeType;
}
@@ -1283,7 +1278,7 @@ var dart, _js_helper, _js_primitives, dartx;
}
next() {
let i = this.dartIterator;
- var done = !i.moveNext();
+ let done = !i.moveNext();
return { done: done, value: done ? void 0 : i.current };
}
}
@@ -1298,97 +1293,145 @@ var dart, _js_helper, _js_primitives, dartx;
dart.global = window || global;
dart.JsSymbol = Symbol;
- // All libraries, including those that have referenced (lazyImport),
- // but not yet loaded.
- var libraries = new Map();
-
- // Completed libraries.
- var loadedLibraries = new Set();
-
- // Import a library by name.
- // This is exported for REPL / JS interop convenience.
- function import_(name) {
- let loaded = loadedLibraries.has(name);
- let value = libraries[name];
- // TODO(vsm): Change this to a hard throw.
- // For now, we're missing some libraries. E.g., dart:js:
- // https://github.com/dart-lang/dev_compiler/issues/168
- if (!loaded) {
- console.warn('Missing required module: ' + name);
- } else if (!value) {
- throwRuntimeError('Library import error: ' + name)
+ // Module support. This is a simplified module system for Dart.
+ // Longer term, we can easily migrate to an existing JS module system:
+ // ES6, AMD, RequireJS, ....
+
+ class LibraryLoader {
+ constructor(name, defaultValue, imports, lazyImports, loader) {
+ this._name = name;
+ this._library = defaultValue ? defaultValue : {};
+ this._imports = imports;
+ this._lazyImports = lazyImports;
+ this._loader = loader;
+
+ // Cyclic import detection
+ this._state = LibraryLoader.NOT_LOADED;
}
- return value;
- }
- dart.import = import_;
- function initializeLibraryStub(name) {
- // Create the library object if necessary.
- if (!libraries[name]) {
- libraries[name] = {};
+ loadImports(pendingSet) {
+ return this.handleImports(this._imports, (lib) => lib.load(pendingSet));
+ }
+
+ deferLazyImports(pendingSet) {
+ return this.handleImports(this._lazyImports,
+ (lib) => {
+ pendingSet.add(lib._name);
+ return lib.stub();
+ });
}
- return libraries[name];
- }
- const lazyImport = initializeLibraryStub;
- function defineLibrary(name, defaultValue) {
- if (loadedLibraries.has(name)) {
- throwRuntimeError('Library is already defined: ' + name);
+ loadLazyImports(pendingSet) {
+ return this.handleImports(pendingSet, (lib) => lib.load());
}
- var value;
- if (defaultValue) {
- var oldValue = libraries[name];
- if (oldValue && oldValue != defaultValue) {
- throwRuntimeError(
- `Library ${name} cannot be redefined to ${defaultValue}`);
+
+ handleImports(list, handler) {
+ let results = [];
+ for (let name of list) {
+ let lib = libraries[name];
+ if (!lib) {
+ throwRuntimeError('Library not available: ' + name);
+ }
+ results.push(handler(lib));
}
- libraries[name] = value = defaultValue;
- } else {
- value = initializeLibraryStub(name);
+ return results;
}
- loadedLibraries.add(name);
- return value;
- }
- function library(name, defaultValue, imports, lazyImports, module) {
- var args = [];
- var lib = defineLibrary(name, defaultValue);
- args.push(lib);
- for (var i = 0; i < imports.length; ++i) {
- lib = import_(imports[i]);
- args.push(lib);
+ load(inheritedPendingSet) {
+ // Check for cycles
+ if (this._state == LibraryLoader.LOADING) {
+ throwRuntimeError('Circular dependence on library: ' + this._name);
+ } else if (this._state >= LibraryLoader.LOADED) {
+ return this._library;
+ }
+ this._state = LibraryLoader.LOADING;
+
+ // Handle imports and record lazy imports
+ let pendingSet = inheritedPendingSet ? inheritedPendingSet : new Set();
+ let args = this.loadImports(pendingSet);
+ args = args.concat(this.deferLazyImports(pendingSet));
+
+ // Load the library
+ args.unshift(this._library);
+ this._loader.apply(null, args);
+ this._state = LibraryLoader.LOADED;
+
+ // Handle lazy imports
+ if (inheritedPendingSet === void 0) {
+ // Drain the queue
+ this.loadLazyImports(pendingSet);
+ }
+ this._state = LibraryLoader.READY;
+ return this._library;
}
- for (var i = 0; i < lazyImports.length; ++i) {
- lib = lazyImport(lazyImports[i]);
- args.push(lib);
+
+ stub() {
+ return this._library;
}
- module.apply(null, args);
+ }
+ LibraryLoader.NOT_LOADED = 0;
+ LibraryLoader.LOADING = 1;
+ LibraryLoader.LOADED = 2;
+ LibraryLoader.READY = 3;
+
+ // Map from name to LibraryLoader
+ let libraries = new Map();
+
+ function library(name, defaultValue, imports, lazyImports, loader) {
+ libraries[name] =
+ new LibraryLoader(name, defaultValue, imports, lazyImports, loader);
}
dart.library = library;
+ function import_(libraryName) {
+ bootstrap();
+ let loader = libraries[libraryName];
+ return loader.load();
+ }
+ dart.import = import_;
+
function start(libraryName) {
- let lib = import_(libraryName);
- _isolate_helper.startRootIsolate(lib.main, []);
+ let library = import_(libraryName);
+ _isolate_helper.startRootIsolate(library.main, []);
}
dart.start = start;
- let core = lazyImport('dart/core');
- let collection = lazyImport('dart/collection');
- let async = lazyImport('dart/async');
- let _interceptors = lazyImport('dart/_interceptors');
- let _isolate_helper = lazyImport('dart/_isolate_helper');
- let _js_helper = lazyImport('dart/_js_helper');
- _js_helper.checkNum = notNull;
- let _js_primitives = lazyImport('dart/_js_primitives');
- _js_primitives.printString = (s) => console.log(s);
-
- // TODO(vsm): DOM facades?
- // See: https://github.com/dart-lang/dev_compiler/issues/173
- NodeList.prototype.get = function(i) { return this[i]; };
- NamedNodeMap.prototype.get = function(i) { return this[i]; };
- DOMTokenList.prototype.get = function(i) { return this[i]; };
-
- /** Dart extension members. */
- dartx = dartx || {};
-
+ // Libraries used in this file.
+ let core;
+ let collection;
+ let async;
+ let _interceptors;
+ let _isolate_helper;
+ let _js_helper;
+ let _js_primitives;
+
+ function bootstrap() {
+ if (core) return;
+
+ let lazyImport = (name) => libraries[name].stub();
+
+ core = lazyImport('dart/core');
+ collection = lazyImport('dart/collection');
+ async = lazyImport('dart/async');
+ _interceptors = lazyImport('dart/_interceptors');
+ _isolate_helper = lazyImport('dart/_isolate_helper');
+ _js_helper = lazyImport('dart/_js_helper');
+ _js_helper.checkNum = notNull;
+ _js_primitives = lazyImport('dart/_js_primitives');
+ _js_primitives.printString = (s) => console.log(s);
+
+ // TODO(vsm): DOM facades?
+ // See: https://github.com/dart-lang/dev_compiler/issues/173
+ NodeList.prototype.get = function(i) { return this[i]; };
+ NamedNodeMap.prototype.get = function(i) { return this[i]; };
+ DOMTokenList.prototype.get = function(i) { return this[i]; };
+
+ // TODO(vsm): This is referenced (as init.globalState) from
+ // isolate_helper.dart. Where should it go?
+ // See: https://github.com/dart-lang/dev_compiler/issues/164
+ dart.globalState = null;
+
+ /** Dart extension members. */
+ dartx = dartx || {};
+ }
})(dart || (dart = {}));
« no previous file with comments | « no previous file | test/browser/index.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698