Index: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart |
diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart |
index 32c5a63c9cf6aec66feb5e54b41d750a1bbc2e13..8ad97268607e1d0ac4c6cc22a80126e242ef66d8 100644 |
--- a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart |
+++ b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart |
@@ -132,7 +132,9 @@ class ModelEmitter { |
// deferred hash (which depends on the output) when emitting the main |
// fragment. |
fragments.skip(1).forEach((DeferredFragment deferredUnit) { |
- js.Expression ast = emitDeferredFragment(deferredUnit, program.holders); |
+ List<String> types = program.metadataTypes[deferredUnit.outputUnit]; |
+ js.Expression ast = emitDeferredFragment(types, deferredUnit, |
+ program.holders); |
String code = js.prettyPrint(ast, compiler).getText(); |
totalSize += code.length; |
compiler.outputProvider(deferredUnit.outputFileName, deferredExtension) |
@@ -384,15 +386,19 @@ class ModelEmitter { |
globals.add(new js.Property(js.string(IS_HUNK_INITIALIZED), |
isHunkInitializedFunction)); |
+ js.Expression typesAccess = generateEmbeddedGlobalAccess(TYPES); |
+ |
/// See [emitEmbeddedGlobalsForDeferredLoading] for the format of the |
/// deferred hunk. |
js.Expression initializeLoadedHunkFunction = |
js.js(""" |
function(hash) { |
var hunk = $deferredInitializersGlobal[hash]; |
- $setupProgramName(hunk[0]); |
+ $setupProgramName(hunk[0], #typesAccess.length); |
eval(hunk[1]); |
- }"""); |
+ var deferredTypes = eval(hunk[2]); |
+ #typesAccess.push.apply(#typesAccess, deferredTypes); |
+ }""", {'typesAccess': typesAccess}); |
globals.add(new js.Property(js.string(INITIALIZE_LOADED_HUNK), |
initializeLoadedHunkFunction)); |
@@ -420,12 +426,16 @@ class ModelEmitter { |
} |
metadataGlobals.add(createGlobal(program.metadata, METADATA)); |
- metadataGlobals.add(createGlobal(program.metadataTypes, TYPES)); |
+ List<String> types = |
+ program.metadataTypes[program.fragments.first.outputUnit]; |
+ if (types == null) types = <String>[]; |
+ metadataGlobals.add(createGlobal(types, TYPES)); |
return metadataGlobals; |
} |
- js.Expression emitDeferredFragment(DeferredFragment fragment, |
+ js.Expression emitDeferredFragment(List<String> types, |
+ DeferredFragment fragment, |
List<Holder> holders) { |
// TODO(floitsch): initialize eager classes. |
// TODO(floitsch): the hash must depend on the output. |
@@ -447,8 +457,14 @@ class ModelEmitter { |
emitEagerClassInitializations(fragment.libraries); |
js.LiteralString immediateString = unparse(compiler, immediateCode); |
+ |
+ js.Expression deferredTypes = types == null |
+ ? js.string("[]") |
+ : js.string("[${types.join(",")}]"); |
+ |
js.ArrayInitializer hunk = |
- new js.ArrayInitializer([deferredArray, immediateString]); |
+ new js.ArrayInitializer([deferredArray, immediateString, |
+ deferredTypes]); |
return js.js("$deferredInitializersGlobal[$hash] = #", hunk); |
} |
@@ -663,7 +679,7 @@ class ModelEmitter { |
/// * [DartMethod.optionalParameterDefaultValues] |
static final String parseFunctionDescriptorBoilerplate = r""" |
-function parseFunctionDescriptor(proto, name, descriptor) { |
+function parseFunctionDescriptor(proto, name, descriptor, typesOffset) { |
if (descriptor instanceof Array) { |
// 'pos' points to the last read entry. |
var f, pos = -1; |
@@ -685,6 +701,9 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
isIntercepted = descriptor[++pos]; |
tearOffName = descriptor[++pos]; |
reflectionInfo = descriptor[++pos]; |
+ if (typeof reflectionInfo == "number") { |
+ reflectionInfo = reflectionInfo + typesOffset; |
+ } |
} |
// We iterate in blocks of 3 but have to stop before we reach the (optional) |
@@ -839,19 +858,20 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
// Counter to generate unique names for tear offs. |
var functionCounter = 0; |
- function $setupProgramName(program) { |
+ function $setupProgramName(program, typesOffset) { |
for (var i = 0; i < program.length - 2; i++) { |
- setupLibrary(program[i]); |
+ setupLibrary(program[i], typesOffset); |
} |
setupLazyStatics(program[i]); |
setupConstants(program[i + 1]); |
} |
- function setupLibrary(library) { |
+ function setupLibrary(library, typesOffset) { |
var statics = library[0]; |
for (var i = 0; i < statics.length; i += 3) { |
var holderIndex = statics[i + 1]; |
- setupStatic(statics[i], holders[holderIndex], statics[i + 2]); |
+ setupStatic(statics[i], holders[holderIndex], statics[i + 2], |
+ typesOffset); |
} |
var classes = library[1]; |
@@ -876,7 +896,7 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
} |
holdersMap[name] = holders[holderIndex]; |
- setupClass(name, holders[holderIndex], cls); |
+ setupClass(name, holders[holderIndex], cls, typesOffset); |
} |
} |
@@ -902,7 +922,7 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
} |
} |
- function setupStatic(name, holder, descriptor) { |
+ function setupStatic(name, holder, descriptor, typesOffset) { |
if (typeof descriptor == 'string') { |
holder[name] = function() { |
if (descriptor == null) { |
@@ -918,7 +938,7 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
} else { |
// Parse the tear off information and generate compile handlers. |
// TODO(herhut): Share parser with instance methods. |
- function compileAllStubs() { |
+ function compileAllStubs(typesOffset) { |
var funs; |
var fun = compile(name, descriptor[0]); |
fun[#callName] = descriptor[1]; |
@@ -936,8 +956,12 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
} |
if (descriptor[2] != null) { // tear-off name. |
// functions, reflectionInfo, isStatic, name, isIntercepted. |
+ var reflectionInfo = descriptor[3]; |
+ if (typeof reflectionInfo == "number") { |
+ reflectionInfo = reflectionInfo + typesOffset; |
+ } |
holder[descriptor[2]] = |
- tearOff(funs, descriptor[3], true, name, false); |
+ tearOff(funs, reflectionInfo, true, name, false); |
} |
if (pos < descriptor.length) { |
fun[#argumentCount] = descriptor[pos]; |
@@ -945,25 +969,25 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
} |
} |
- function setupCompileAllAndDelegateStub(name) { |
+ function setupCompileAllAndDelegateStub(name, typesOffset) { |
holder[name] = function() { |
// The descriptor is null if we already compiled this function. This |
// happens when we have calls to the static as arguments to the |
// static: `foo(foo(499))`; |
if (descriptor != null) { |
- compileAllStubs(); |
+ compileAllStubs(typesOffset); |
descriptor = null; // GC the descriptor. |
} |
return holder[name].apply(this, arguments); |
}; |
} |
- setupCompileAllAndDelegateStub(name); |
+ setupCompileAllAndDelegateStub(name, typesOffset); |
for (var pos = 4; pos < descriptor.length; pos += 3) { |
- setupCompileAllAndDelegateStub(descriptor[pos]); |
+ setupCompileAllAndDelegateStub(descriptor[pos], typesOffset); |
} |
if (descriptor[2] != null) { // tear-off name. |
- setupCompileAllAndDelegateStub(descriptor[2]) |
+ setupCompileAllAndDelegateStub(descriptor[2], typesOffset) |
} |
} |
} |
@@ -1006,11 +1030,11 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
}; |
} |
- function setupClass(name, holder, descriptor) { |
+ function setupClass(name, holder, descriptor, typesOffset) { |
var patch = function() { |
if (patch.ensureResolved == patch) { |
// We have not yet been compiled. |
- var constructor = compileConstructor(name, descriptor); |
+ var constructor = compileConstructor(name, descriptor, typesOffset); |
holder[name] = constructor; |
name = holder = descriptor = null; // GC the captured arguments. |
// Make sure we can invoke 'ensureResolved' multiple times on the patch |
@@ -1039,7 +1063,7 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
#parseFunctionDescriptor; |
- function compileConstructor(name, descriptor) { |
+ function compileConstructor(name, descriptor, typesOffset) { |
descriptor = compile(name, descriptor); |
var prototype = determinePrototype(descriptor); |
var constructor; |
@@ -1062,7 +1086,8 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
} |
for (var i = functionsIndex; i < descriptor.length; i += 2) { |
- parseFunctionDescriptor(prototype, descriptor[i], descriptor[i + 1]); |
+ parseFunctionDescriptor(prototype, descriptor[i], descriptor[i + 1], |
+ typesOffset); |
} |
constructor.builtin\$cls = name; // Needed for RTI. |
@@ -1126,7 +1151,7 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
} |
} |
- $setupProgramName(program); |
+ $setupProgramName(program, 0); |
// Initialize globals. |
#embeddedGlobals; |