Chromium Code Reviews| 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(''' |
|
floitsch
2015/02/09 16:14:23
Copied over from other file. (Start reviewing from
|
| + (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}); |
| + } |
| +} |