| Index: pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
|
| diff --git a/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..474885463f5d25c7bc44f35270a54c83cffded48
|
| --- /dev/null
|
| +++ b/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
|
| @@ -0,0 +1,82 @@
|
| +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
|
| +// 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.
|
| +
|
| +part of dart2js.js_emitter;
|
| +
|
| +class MainCallStubGenerator {
|
| + final Compiler compiler;
|
| + final JavaScriptBackend backend;
|
| + final CodeEmitterTask emitterTask;
|
| +
|
| + MainCallStubGenerator(this.compiler, this.backend, this.emitterTask);
|
| +
|
| + /// Returns the code equivalent to:
|
| + /// `function(args) { $.startRootIsolate(X.main$closure(), args); }`
|
| + jsAst.Expression _buildIsolateSetupClosure(Element appMain,
|
| + Element isolateMain) {
|
| + jsAst.Expression mainAccess =
|
| + emitterTask.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); }',
|
| + [emitterTask.staticFunctionAccess(isolateMain), mainAccess]);
|
| + }
|
| +
|
| +
|
| + jsAst.Statement generateInvokeMain() {
|
| + 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 #(); }',
|
| + emitterTask.staticFunctionAccess(main));
|
| + } else {
|
| + mainCallClosure = emitterTask.staticFunctionAccess(main);
|
| + }
|
| +
|
| + jsAst.Expression currentScriptAccess =
|
| + emitterTask.generateEmbeddedGlobalAccess(embeddedNames.CURRENT_SCRIPT);
|
| +
|
| + // 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.
|
| + return 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});
|
| + }
|
| +}
|
|
|