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

Unified Diff: pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart

Issue 1233693002: dart2js: Add embedded globals to startup emitter. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fix another reference to the moved global. Created 5 years, 5 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 | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 0b44ccc73b8ee0ba7a7f9b35a6b276638efea63b..f11e5ec61de03c315b1fa083437ff3a198454b67 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -237,13 +237,6 @@ var #staticStateDeclaration = {};
// Builds the inheritance structure.
#inheritance;
-// Emits the embedded globals.
-#embeddedGlobals;
-
-// Sets up the native support.
-// Native-support uses setOrUpdateInterceptorsByTag and setOrUpdateLeafTags.
-#nativeSupport;
-
// Instantiates all constants.
#constants;
// Initializes the static non-final fields (with their constant values).
@@ -251,6 +244,13 @@ var #staticStateDeclaration = {};
// Creates lazy getters for statics that must run initializers on first access.
#lazyStatics;
+// Emits the embedded globals.
+#embeddedGlobals;
+
+// Sets up the native support.
+// Native-support uses setOrUpdateInterceptorsByTag and setOrUpdateLeafTags.
+#nativeSupport;
+
// Invokes main (making sure that it records the 'current-script' value).
#invokeMain;
})();
@@ -285,11 +285,6 @@ function(inherit, mixin, lazy, makeConstList, installTearOff,
// Builds the inheritance structure.
#inheritance;
-updateTypes(#types);
-
-// Native-support uses setOrUpdateInterceptorsByTag and setOrUpdateLeafTags.
-#nativeSupport;
-
// Instantiates all constants of this deferred fragment.
// Note that the constant-holder has been updated earlier and storing the
// constant values in the constant-holder makes them available globally.
@@ -298,6 +293,11 @@ updateTypes(#types);
#staticNonFinalFields;
// Creates lazy getters for statics that must run initializers on first access.
#lazyStatics;
+
+updateTypes(#types);
+
+// Native-support uses setOrUpdateInterceptorsByTag and setOrUpdateLeafTags.
+#nativeSupport;
};
// TODO(floitsch): this last line should be outside the AST, since it
// requires to know the hash of the part of the code above this comment.
@@ -861,8 +861,186 @@ class FragmentEmitter {
return new js.Block(statements.toList());
}
- emitEmbeddedGlobals(program) {
- throw new UnimplementedError('emitEmbeddedGlobals');
+ /// Emits the embedded globals that are needed for deferred loading.
+ ///
+ /// This function is only invoked for the main fragment.
+ ///
+ /// The [loadMap] contains a map from load-ids (for each deferred library)
+ /// to the list of generated fragments that must be installed when the
+ /// deferred library is loaded.
+ Iterable<js.Property> emitEmbeddedGlobalsForDeferredLoading(
+ Map<String, List<Fragment>> loadMap) {
+ if (loadMap.isEmpty) return [];
+
+ List<js.Property> globals = <js.Property>[];
+
+ js.ArrayInitializer fragmentUris(List<Fragment> fragments) {
+ return js.stringArray(fragments.map((DeferredFragment fragment) =>
+ "${fragment.outputFileName}.${ModelEmitter.deferredExtension}"));
+ }
+ js.ArrayInitializer fragmentHashes(List<Fragment> fragments) {
+ // TODO(floitsch): the hash must depend on the generated code.
+ return js.numArray(
+ fragments.map((DeferredFragment fragment) => fragment.hashCode));
+ }
+
+ List<js.Property> uris = new List<js.Property>(loadMap.length);
+ List<js.Property> hashes = new List<js.Property>(loadMap.length);
+ int count = 0;
+ loadMap.forEach((String loadId, List<Fragment> fragmentList) {
+ uris[count] =
+ new js.Property(js.string(loadId), fragmentUris(fragmentList));
+ hashes[count] =
+ new js.Property(js.string(loadId), fragmentHashes(fragmentList));
+ count++;
+ });
+
+ globals.add(new js.Property(js.string(DEFERRED_LIBRARY_URIS),
+ new js.ObjectInitializer(uris)));
+ globals.add(new js.Property(js.string(DEFERRED_LIBRARY_HASHES),
+ new js.ObjectInitializer(hashes)));
+ globals.add(new js.Property(js.string(DEFERRED_INITIALIZED),
+ js.js("Object.create(null)")));
+
+ String deferredGlobal = ModelEmitter.deferredInitializersGlobal;
+ js.Expression isHunkLoadedFunction =
+ js.js("function(hash) { return !!$deferredGlobal[hash]; }");
+ globals.add(new js.Property(js.string(IS_HUNK_LOADED),
+ isHunkLoadedFunction));
+
+ js.Expression isHunkInitializedFunction =
+ js.js("function(hash) { return !!#deferredInitialized[hash]; }",
+ {'deferredInitialized':
+ generateEmbeddedGlobalAccess(DEFERRED_INITIALIZED)});
+ globals.add(new js.Property(js.string(IS_HUNK_INITIALIZED),
+ isHunkInitializedFunction));
+
+ /// See [emitEmbeddedGlobalsForDeferredLoading] for the format of the
+ /// deferred hunk.
+ js.Expression initializeLoadedHunkFunction =
+ js.js("""
+ function(hash) {
+ initializeDeferredHunk($deferredGlobal[hash]);
+ #deferredInitialized[hash] = true;
+ }""", {'deferredInitialized':
+ generateEmbeddedGlobalAccess(DEFERRED_INITIALIZED)});
+
+ globals.add(new js.Property(js.string(INITIALIZE_LOADED_HUNK),
+ initializeLoadedHunkFunction));
+
+ return globals;
+ }
+
+ /// Emits the [MANGLED_GLOBAL_NAMES] embedded global.
+ ///
+ /// This global maps minified names for selected classes (some important
+ /// core classes, and some native classes) to their unminified names.
+ js.Property emitMangledGlobalNames() {
+ List<js.Property> names = <js.Property>[];
+
+ // We want to keep the original names for the most common core classes when
+ // calling toString on them.
+ List<ClassElement> nativeClassesNeedingUnmangledName =
+ [compiler.intClass, compiler.doubleClass, compiler.numClass,
+ compiler.stringClass, compiler.boolClass, compiler.nullClass,
+ compiler.listClass];
+ // TODO(floitsch): this should probably be on a per-fragment basis.
+ nativeClassesNeedingUnmangledName.forEach((element) {
+ names.add(new js.Property(js.quoteName(namer.className(element)),
+ js.string(element.name)));
+ });
+
+ return new js.Property(js.string(MANGLED_GLOBAL_NAMES),
+ new js.ObjectInitializer(names));
+ }
+
+ /// Emits the [GET_TYPE_FROM_NAME] embedded global.
+ ///
+ /// This embedded global provides a way to go from a class name (which is
+ /// also the constructor's name) to the constructor itself.
+ js.Property emitGetTypeFromName() {
+ // TODO(floitsch): Fix getTypeFromName. It's too inefficient.
+ // The current implementation relies on the fact that the names in holders
+ // are unique across all holders.
+ // TODO(floitsch): constants and other globals may share the same name.
+ // If a global happens to have the same (minified) name this code breaks.
+ // A follow-up CL has a fix for this.
+ js.Expression function =
+ js.js( """function(name) {
+ for (var i = 0; i < holders.length; i++) {
+ // Relies on the fact that all variables are unique.
+ if (holders[i][name]) return holders[i][name];
+ }
+ }""");
+ return new js.Property(js.string(GET_TYPE_FROM_NAME), function);
+ }
+
+ /// Emits the [METADATA] embedded global.
+ ///
+ /// The metadata itself has already been computed earlier and is stored in
+ /// the [program].
+ List<js.Property> emitMetadata(Program program) {
+ List<js.Property> metadataGlobals = <js.Property>[];
+
+ js.Property createGlobal(js.Expression metadata, String global) {
+ return new js.Property(js.string(global), metadata);
+ }
+
+ metadataGlobals.add(createGlobal(program.metadata, METADATA));
+ js.Expression types =
+ program.metadataTypesForOutputUnit(program.mainFragment.outputUnit);
+ metadataGlobals.add(createGlobal(types, TYPES));
+
+ return metadataGlobals;
+ }
+
+ /// Emits all embedded globals.
+ js.Block emitEmbeddedGlobals(Program program) {
+ List<js.Property> globals = <js.Property>[];
+
+ if (program.loadMap.isNotEmpty) {
+ globals.addAll(emitEmbeddedGlobalsForDeferredLoading(program.loadMap));
+ }
+
+ if (program.typeToInterceptorMap != null) {
+ globals.add(new js.Property(js.string(TYPE_TO_INTERCEPTOR_MAP),
+ program.typeToInterceptorMap));
+ }
+
+ if (program.hasIsolateSupport) {
+ String staticStateName = namer.staticStateHolder;
+ // TODO(floitsch): this doesn't create a new isolate, but just reuses
+ // the current static state. Since we don't run multiple isolates in the
+ // same JavaScript context (except for testing) this shouldn't have any
+ // impact on real-world programs, though.
+ globals.add(
+ new js.Property(js.string(CREATE_NEW_ISOLATE),
+ js.js('function () { return $staticStateName; }')));
+ // TODO(floitsch): add remaining isolate functions.
+ }
+
+ globals.add(emitMangledGlobalNames());
+
+ globals.add(emitGetTypeFromName());
+
+ globals.addAll(emitMetadata(program));
+
+ if (program.needsNativeSupport) {
+ globals.add(new js.Property(js.string(INTERCEPTORS_BY_TAG),
+ new js.LiteralNull()));
+ globals.add(new js.Property(js.string(LEAF_TAGS),
+ new js.LiteralNull()));
+ }
+
+ js.ObjectInitializer globalsObject = new js.ObjectInitializer(globals);
+
+ List<js.Statement> statements =
+ [new js.ExpressionStatement(
+ new js.VariableDeclarationList(
+ [new js.VariableInitialization(
+ new js.VariableDeclaration("init", allowRename: false),
+ globalsObject)]))];
Siggi Cherem (dart-lang) 2015/07/22 23:16:29 this makes me wonder if there are more features we
floitsch 2015/07/29 17:47:59 I actually think that we should be able to rename
+ return new js.Block(statements);
}
emitNativeSupport(fragment) {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698