| Index: pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
|
| diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
|
| index ddef481c0b155591c0bcd194b5f9152dbd151ee7..c15f2ed97058e1a61077891f4364439c9f7072f5 100644
|
| --- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
|
| +++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
|
| @@ -921,8 +921,32 @@ class OldEmitter implements Emitter {
|
| backend.rti.getFunctionThatReturnsNullName]);
|
| }
|
|
|
| - emitMain(CodeOutput output, jsAst.Statement invokeMain) {
|
| + /// Returns the code equivalent to:
|
| + /// `function(args) { $.startRootIsolate(X.main$closure(), args); }`
|
| + jsAst.Expression buildIsolateSetupClosure(Element appMain,
|
| + Element isolateMain) {
|
| + jsAst.Expression mainAccess = isolateStaticClosureAccess(appMain);
|
| + // Since we pass the closurized version of the main method to
|
| + // the isolate method, we must make sure that it exists.
|
| + return js('function(a){ #(#, a); }',
|
| + [backend.emitter.staticFunctionAccess(isolateMain), mainAccess]);
|
| + }
|
| +
|
| + emitMain(CodeOutput output) {
|
| if (compiler.isMockCompilation) return;
|
| + Element main = compiler.mainFunction;
|
| + jsAst.Expression mainCallClosure = null;
|
| + if (compiler.hasIsolateSupport) {
|
| + Element isolateMain =
|
| + backend.isolateHelperLibrary.find(JavaScriptBackend.START_ROOT_ISOLATE);
|
| + mainCallClosure = buildIsolateSetupClosure(main, isolateMain);
|
| + } else if (compiler.hasIncrementalSupport) {
|
| + mainCallClosure = js(
|
| + 'function() { return #(); }',
|
| + backend.emitter.staticFunctionAccess(main));
|
| + } else {
|
| + mainCallClosure = backend.emitter.staticFunctionAccess(main);
|
| + }
|
|
|
| if (NativeGenerator.needsIsolateAffinityTagInitialization(backend)) {
|
| jsAst.Statement nativeBoilerPlate =
|
| @@ -934,7 +958,47 @@ class OldEmitter implements Emitter {
|
| nativeBoilerPlate, compiler, monitor: compiler.dumpInfoTask));
|
| }
|
|
|
| + jsAst.Expression currentScriptAccess =
|
| + generateEmbeddedGlobalAccess(embeddedNames.CURRENT_SCRIPT);
|
| +
|
| addComment('BEGIN invoke [main].', output);
|
| + // This code finds the currently executing script by listening to the
|
| + // onload event of all script tags and getting the first script which
|
| + // finishes. Since onload is called immediately after execution this should
|
| + // not substantially change execution order.
|
| + jsAst.Statement invokeMain = js.statement('''
|
| +(function (callback) {
|
| + if (typeof document === "undefined") {
|
| + callback(null);
|
| + return;
|
| + }
|
| + if (document.currentScript) {
|
| + callback(document.currentScript);
|
| + return;
|
| + }
|
| +
|
| + var scripts = document.scripts;
|
| + function onLoad(event) {
|
| + for (var i = 0; i < scripts.length; ++i) {
|
| + scripts[i].removeEventListener("load", onLoad, false);
|
| + }
|
| + callback(event.target);
|
| + }
|
| + for (var i = 0; i < scripts.length; ++i) {
|
| + scripts[i].addEventListener("load", onLoad, false);
|
| + }
|
| +})(function(currentScript) {
|
| + #currentScript = currentScript;
|
| +
|
| + if (typeof dartMainRunner === "function") {
|
| + dartMainRunner(#mainCallClosure, []);
|
| + } else {
|
| + #mainCallClosure([]);
|
| + }
|
| +})''', {'currentScript': currentScriptAccess,
|
| + 'mainCallClosure': mainCallClosure});
|
| +
|
| + output.add(';');
|
| output.addBuffer(jsAst.prettyPrint(invokeMain,
|
| compiler, monitor: compiler.dumpInfoTask));
|
| output.add(N);
|
| @@ -1301,7 +1365,7 @@ class OldEmitter implements Emitter {
|
|
|
| void emitMainOutputUnit(Program program,
|
| Map<OutputUnit, String> deferredLoadHashes) {
|
| - MainFragment mainFragment = program.fragments.first;
|
| + Fragment mainFragment = program.fragments.first;
|
| OutputUnit mainOutputUnit = mainFragment.outputUnit;
|
|
|
| LineColumnCollector lineColumnCollector;
|
| @@ -1515,7 +1579,7 @@ class OldEmitter implements Emitter {
|
| jsAst.FunctionDeclaration precompiledFunctionAst =
|
| buildCspPrecompiledFunctionFor(mainOutputUnit);
|
| emitInitFunction(mainOutput);
|
| - emitMain(mainOutput, mainFragment.invokeMain);
|
| + emitMain(mainOutput);
|
| mainOutput.add('})()\n');
|
|
|
| if (compiler.useContentSecurityPolicy) {
|
|
|