Chromium Code Reviews| Index: pkg/fletchc/lib/dart2js_bridge.dart |
| diff --git a/pkg/fletchc/lib/dart2js_bridge.dart b/pkg/fletchc/lib/dart2js_bridge.dart |
| index 6685fdd5d39030f0638c6eec6d2749b3d02f5416..c046015769e1b9f30108b869b823b26ee5828a1f 100644 |
| --- a/pkg/fletchc/lib/dart2js_bridge.dart |
| +++ b/pkg/fletchc/lib/dart2js_bridge.dart |
| @@ -2,14 +2,343 @@ |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE.md file. |
| -import 'package:compiler/compiler.dart' as compiler; |
| +import 'dart:io' show |
|
kasperl
2015/02/10 19:56:57
Maybe give this a library a name?
ahe
2015/02/11 13:47:17
Done.
|
| + File, |
| + Platform; |
| -import 'package:semantic_visitor/semantic_visitor.dart' as semantic_visitor; |
| +import 'package:compiler/compiler.dart' as api; |
| import 'package:sharedfrontend/elements.dart' as elements; |
| -main() { |
| - print(compiler.compile); |
| - print(semantic_visitor.SemanticVisitor); |
| - print(elements.Element); |
| +import 'package:compiler/src/apiimpl.dart' as apiimpl; |
| + |
| +import 'package:compiler/src/dart2jslib.dart' as dart2js; |
| + |
| +import 'package:compiler/src/source_file_provider.dart' show |
| + FormattingDiagnosticHandler; |
| + |
| +import 'package:dart2js_incremental/compiler.dart' show |
| + OutputProvider; |
| + |
| +import 'package:compiler/src/filenames.dart' show |
| + appendSlash; |
| + |
| +import 'package:semantic_visitor/semantic_visitor.dart' show |
| + SemanticVisitor; |
| + |
| +import 'package:compiler/src/elements/elements.dart'; |
| +import 'package:compiler/src/resolution/resolution.dart'; |
| +import 'package:compiler/src/tree/tree.dart'; |
| +import 'package:compiler/src/universe/universe.dart'; |
| +import 'package:compiler/src/util/util.dart' show Spannable; |
| +import 'package:compiler/src/dart_types.dart'; |
| + |
| +import 'bytecodes.dart'; |
| + |
| +main(List<String> arguments) { |
| + FormattingDiagnosticHandler handler = new FormattingDiagnosticHandler() |
| + ..throwOnError = false; |
| + |
| + OutputProvider outputProvider = new OutputProvider(); |
| + |
| + Uri myLocation = Uri.base.resolveUri(Platform.script); |
| + if (myLocation.scheme == 'package') { |
| + Uri runtimePackageRoot = |
| + Uri.base.resolve(appendSlash(Platform.packageRoot)); |
| + myLocation = |
|
kasperl
2015/02/10 19:56:57
My usual preference is to add a few more local var
ahe
2015/02/11 13:47:18
Done.
|
| + new Uri.file( |
| + new File.fromUri(runtimePackageRoot.resolve(myLocation.path)) |
| + .resolveSymbolicLinksSync()); |
| + } |
| + |
| + Uri script = Uri.base.resolve(arguments.single); |
| + |
| + Uri libraryRoot = myLocation.resolve('../../../../dart/sdk/'); |
| + |
| + Uri packageRoot = script.resolve('packages/'); |
| + |
| + List<String> options = <String>[]; |
| + |
| + Map<String, dynamic> environment = <String, dynamic>{}; |
| + |
| + FletchCompiler compiler = new FletchCompiler( |
| + handler.provider, |
| + outputProvider, |
| + handler, |
| + libraryRoot, |
| + packageRoot, |
| + options, |
| + environment); |
| + |
| + compiler.run(script); |
| +} |
| + |
| +abstract class FletchCompilerHack extends apiimpl.Compiler { |
| + FletchCompilerHack( |
| + api.CompilerInputProvider provider, |
| + api.CompilerOutputProvider outputProvider, |
| + api.DiagnosticHandler handler, |
| + Uri libraryRoot, |
| + Uri packageRoot, |
| + List<String> options, |
| + Map<String, dynamic> environment) |
| + : super(provider, outputProvider, handler, libraryRoot, packageRoot, |
| + options, environment) { |
| + switchBackendHack(); |
| + } |
| + |
| + void switchBackendHack() { |
| + // TODO(ahe): Modify dart2js to support a custom backend directly, and |
| + // remove this method. |
| + int backendTaskCount = backend.tasks.length; |
| + int apiimplTaskCount = 2; |
| + int baseTaskCount = tasks.length - backendTaskCount - apiimplTaskCount; |
| + |
| + tasks.removeRange(baseTaskCount, baseTaskCount + backendTaskCount); |
| + |
| + backend = new FletchBackend(this); |
| + tasks.addAll(backend.tasks); |
| + } |
| +} |
| + |
| +class FletchCompiler extends FletchCompilerHack { |
| + FletchCompiler( |
| + api.CompilerInputProvider provider, |
| + api.CompilerOutputProvider outputProvider, |
| + api.DiagnosticHandler handler, |
| + Uri libraryRoot, |
| + Uri packageRoot, |
| + List<String> options, |
| + Map<String, dynamic> environment) |
| + : super(provider, outputProvider, handler, libraryRoot, packageRoot, |
| + ['--output-type=dart']..addAll(options), environment); |
| + |
| + void computeMain() { |
| + if (mainApp == null) return; |
| + |
| + mainFunction = mainApp.findLocal("_entry"); |
| + } |
| + |
| + void onLibraryCreated(elements.LibraryElement library) { |
| + // TODO(ahe): Remove this. |
| + library.canUseNative = true; |
| + super.onLibraryCreated(library); |
| + } |
| +} |
| + |
| +class FletchBackend extends dart2js.Backend { |
| + final FletchResolutionCallbacks resolutionCallbacks = |
| + new FletchResolutionCallbacks(); |
| + |
| + FletchBackend(dart2js.Compiler compiler) |
| + : super(compiler); |
| + |
| + List<CompilerTask> get tasks => <CompilerTask>[]; |
| + |
| + dart2js.ConstantSystem get constantSystem { |
| + throw new UnsupportedError("get constantSystem"); |
| + } |
| + |
| + dart2js.BackendConstantEnvironment get constants { |
| + throw new UnsupportedError("get constants"); |
| + } |
| + |
| + dart2js.ConstantCompilerTask get constantCompilerTask { |
| + throw new UnsupportedError("get constantCompilerTask"); |
| + } |
| + |
| + void enqueueHelpers(dart2js.ResolutionEnqueuer world, dart2js.Registry registry) { |
|
kasperl
2015/02/10 19:56:57
Long line.
ahe
2015/02/11 13:47:18
Done.
|
| + } |
| + |
| + void codegen(dart2js.CodegenWorkItem work) { |
| + } |
| + |
| + bool get canHandleCompilationFailed => true; |
| + |
| + int assembleProgram() { |
| + compiler.reportHint( |
| + compiler.mainFunction, |
| + dart2js.MessageKind.GENERIC, |
| + {'text': 'Compiling ${compiler.mainFunction.name}'}); |
| + |
| + FletchVisitor visitor = new FletchVisitor(compiler.mainFunction); |
| + compiler.mainFunction.node.accept(visitor); |
| + print("Constants"); |
| + visitor.constants.forEach((constant, int index) { |
| + print(" #$index: $constant"); |
| + }); |
| + |
| + print("Bytecodes:"); |
| + int offset = 0; |
| + for (Bytecode bytecode in visitor.bytecodes) { |
| + print(" $offset: $bytecode"); |
| + offset += bytecode.size; |
| + } |
| + } |
| +} |
| + |
| +class FletchResolutionCallbacks extends dart2js.ResolutionCallbacks { |
| +} |
| + |
| +class FletchVisitor extends SemanticVisitor { |
|
kasperl
2015/02/10 19:56:56
FletchMethodVisitor perhaps?
ahe
2015/02/11 13:47:18
I think I like "BytecodeBuilder".
|
| + final List<Bytecode> bytecodes = <Bytecode>[]; |
| + |
| + final Map<dynamic, int> constants = <dynamic, int>{}; |
| + |
| + FletchVisitor(element) |
| + : super(element.resolvedAst.elements); |
| + |
| + void visitStaticMethodInvocation( |
| + Send node, |
| + /* MethodElement */ element, |
| + NodeList arguments, |
| + Selector selector) { |
| + arguments.accept(this); |
| + int id = constants.putIfAbsent(element, () => constants.length); |
|
kasperl
2015/02/10 19:56:56
I'd consider adding a helper method for turning a
ahe
2015/02/11 13:47:18
Done.
|
| + bytecodes.add(new InvokeStaticUnfold(id)); |
| + bytecodes.add(const Pop()); |
| + } |
| + |
| + void visitLiteralString(LiteralString node) { |
| + int id = constants.putIfAbsent( |
| + node.dartString.slowToString(), () => constants.length); |
| + bytecodes.add(new LoadConstUnfold(id)); |
| + } |
| + |
| + void visitLiteralInt(LiteralInt node) { |
| + int id = constants.putIfAbsent(node.value, () => constants.length); |
| + bytecodes.add(new LoadConstUnfold(id)); |
| + } |
| + |
| + |
| + void visitLiteral(Literal node) { |
| + print("literal ${node}"); |
|
kasperl
2015/02/10 19:56:57
Maybe just remove this printing again?
ahe
2015/02/11 13:47:18
Done.
|
| + } |
| + |
| + void visitFunctionExpression(FunctionExpression node) { |
| + node.body.accept(this); |
| + } |
| + |
| + void visitBlock(Block node) { |
| + node.visitChildren(this); |
| + } |
| + |
| + void visitNodeList(NodeList node) { |
| + node.visitChildren(this); |
| + } |
| + |
| + void visitExpressionStatement(ExpressionStatement node) { |
| + node.visitChildren(this); |
|
kasperl
2015/02/10 19:56:56
How about moving the pop from visitStaticMethodInv
ahe
2015/02/10 21:38:07
Yes, of course!
|
| + } |
| + |
| + void visitParameterAccess(Send node, ParameterElement element); |
| + |
| + void visitParameterAssignment(SendSet node, ParameterElement element, Node rhs); |
|
kasperl
2015/02/10 19:56:57
Long line.
ahe
2015/02/11 13:47:18
Done.
|
| + void visitParameterInvocation(Send node, |
| + ParameterElement element, |
| + NodeList arguments, |
| + Selector selector); |
| + |
| + void visitLocalVariableAccess(Send node, LocalVariableElement element); |
| + void visitLocalVariableAssignment(SendSet node, |
| + LocalVariableElement element, |
| + Node rhs); |
| + void visitLocalVariableInvocation(Send node, |
| + LocalVariableElement element, |
| + NodeList arguments, |
| + Selector selector); |
| + |
| + void visitLocalFunctionAccess(Send node, LocalFunctionElement element); |
| + void visitLocalFunctionAssignment(SendSet node, |
| + LocalFunctionElement element, |
| + Node rhs, |
| + Selector selector); |
| + void visitLocalFunctionInvocation(Send node, |
| + LocalFunctionElement element, |
| + NodeList arguments, |
| + Selector selector); |
| + |
| + void visitDynamicAccess(Send node, Selector selector); |
| + void visitDynamicAssignment(SendSet node, Selector selector, Node rhs); |
| + void visitDynamicInvocation(Send node, |
| + NodeList arguments, |
| + Selector selector); |
| + |
| + void visitStaticFieldAccess(Send node, FieldElement element); |
| + void visitStaticFieldAssignment(SendSet node, FieldElement element, Node rhs); |
| + void visitStaticFieldInvocation(Send node, |
| + FieldElement element, |
| + NodeList arguments, |
| + Selector selector); |
| + |
| + void visitStaticMethodAccess(Send node, MethodElement element); |
| + |
| + void visitStaticPropertyAccess(Send node, FunctionElement element); |
| + void visitStaticPropertyAssignment(SendSet node, |
| + FunctionElement element, |
| + Node rhs); |
| + void visitStaticPropertyInvocation(Send node, |
| + FieldElement element, |
| + NodeList arguments, |
| + Selector selector); |
| + |
| + void visitTopLevelFieldAccess(Send node, FieldElement element); |
| + void visitTopLevelFieldAssignment(SendSet node, FieldElement element, Node rhs); |
|
kasperl
2015/02/10 19:56:57
Long line.
ahe
2015/02/11 13:47:18
Done.
|
| + void visitTopLevelFieldInvocation(Send node, |
| + FieldElement element, |
| + NodeList arguments, |
| + Selector selector); |
| + |
| + void visitTopLevelMethodAccess(Send node, MethodElement element); |
| + void visitTopLevelMethodInvocation(Send node, |
| + MethodElement element, |
| + NodeList arguments, |
| + Selector selector); |
| + |
| + void visitTopLevelPropertyAccess(Send node, FunctionElement element); |
| + void visitTopLevelPropertyAssignment(SendSet node, |
| + FunctionElement element, |
| + Node rhs); |
| + void visitTopLevelPropertyInvocation(Send node, |
| + FieldElement element, |
| + NodeList arguments, |
| + Selector selector); |
| + |
| + void visitClassTypeLiteralAccess(Send node, ClassElement element); |
| + void visitClassTypeLiteralInvocation(Send node, |
| + ClassElement element, |
| + NodeList arguments, |
| + Selector selector); |
| + void visitClassTypeLiteralAssignment(SendSet node, |
| + ClassElement element, |
| + Node rhs); |
| + |
| + void visitTypedefTypeLiteralAccess(Send node, TypedefElement element); |
| + |
| + void visitTypedefTypeLiteralInvocation(Send node, |
| + TypedefElement element, |
| + NodeList arguments, |
| + Selector selector); |
| + |
| + void visitTypedefTypeLiteralAssignment(SendSet node, |
| + TypedefElement element, |
| + Node rhs); |
| + |
| + void visitTypeVariableTypeLiteralAccess(Send node, TypeVariableElement element); |
|
kasperl
2015/02/10 19:56:57
Long line.
ahe
2015/02/11 13:47:17
Done.
|
| + |
| + void visitTypeVariableTypeLiteralInvocation(Send node, |
| + TypeVariableElement element, |
| + NodeList arguments, |
| + Selector selector); |
| + |
| + void visitTypeVariableTypeLiteralAssignment(SendSet node, |
| + TypeVariableElement element, |
| + Node rhs); |
| + |
| + void visitDynamicTypeLiteralAccess(Send node); |
| + |
| + void visitAssert(Send node, Node expression); |
| + |
| + internalError(Spannable spannable, String reason); |
| + |
| } |