| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart2js.ir_builder; | 5 library dart2js.ir_builder; |
| 6 | 6 |
| 7 import 'ir_nodes.dart' as ir; | 7 import 'ir_nodes.dart' as ir; |
| 8 import '../elements/elements.dart'; | 8 import '../elements/elements.dart'; |
| 9 import '../dart2jslib.dart'; | 9 import '../dart2jslib.dart'; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 if (canBuild(element)) { | 52 if (canBuild(element)) { |
| 53 element = element.implementation; | 53 element = element.implementation; |
| 54 | 54 |
| 55 SourceFile sourceFile = elementSourceFile(element); | 55 SourceFile sourceFile = elementSourceFile(element); |
| 56 IrBuilder builder = | 56 IrBuilder builder = |
| 57 new IrBuilder(elementsMapping, compiler, sourceFile); | 57 new IrBuilder(elementsMapping, compiler, sourceFile); |
| 58 ir.FunctionDefinition function; | 58 ir.FunctionDefinition function; |
| 59 ElementKind kind = element.kind; | 59 ElementKind kind = element.kind; |
| 60 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) { | 60 if (kind == ElementKind.GENERATIVE_CONSTRUCTOR) { |
| 61 // TODO(lry): build ir for constructors. | 61 // TODO(lry): build ir for constructors. |
| 62 } else if (element.isDeferredLoaderGetter()) { | 62 } else if (element.isDeferredLoaderGetter) { |
| 63 // TODO(sigurdm): Build ir for deferred loader functions. | 63 // TODO(sigurdm): Build ir for deferred loader functions. |
| 64 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY || | 64 } else if (kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY || |
| 65 kind == ElementKind.FUNCTION || | 65 kind == ElementKind.FUNCTION || |
| 66 kind == ElementKind.GETTER || | 66 kind == ElementKind.GETTER || |
| 67 kind == ElementKind.SETTER) { | 67 kind == ElementKind.SETTER) { |
| 68 function = builder.buildFunction(element); | 68 function = builder.buildFunction(element); |
| 69 } else if (kind == ElementKind.FIELD) { | 69 } else if (kind == ElementKind.FIELD) { |
| 70 // TODO(lry): build ir for lazy initializers of static fields. | 70 // TODO(lry): build ir for lazy initializers of static fields. |
| 71 } else { | 71 } else { |
| 72 compiler.internalError(element, 'Unexpected element kind $kind.'); | 72 compiler.internalError(element, 'Unexpected element kind $kind.'); |
| 73 } | 73 } |
| 74 | 74 |
| 75 if (function != null) { | 75 if (function != null) { |
| 76 assert(() { | 76 assert(() { |
| 77 // In host-checked mode, serialize and de-serialize the IrNode. | 77 // In host-checked mode, serialize and de-serialize the IrNode. |
| 78 LibraryElement library = element.declaration.getLibrary(); | 78 LibraryElement library = element.declaration.library; |
| 79 IrConstantPool constantPool = IrConstantPool.forLibrary(library); | 79 IrConstantPool constantPool = IrConstantPool.forLibrary(library); |
| 80 List<int> data = function.pickle(constantPool); | 80 List<int> data = function.pickle(constantPool); |
| 81 function = new Unpickler(compiler, constantPool).unpickle(data); | 81 function = new Unpickler(compiler, constantPool).unpickle(data); |
| 82 return true; | 82 return true; |
| 83 }); | 83 }); |
| 84 nodes[element] = function; | 84 nodes[element] = function; |
| 85 compiler.tracer.traceCompilation(element.name, null, compiler); | 85 compiler.tracer.traceCompilation(element.name, null, compiler); |
| 86 compiler.tracer.traceGraph("IR Builder", function); | 86 compiler.tracer.traceGraph("IR Builder", function); |
| 87 } | 87 } |
| 88 } | 88 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 114 bool parameters_ok = true; | 114 bool parameters_ok = true; |
| 115 signature.forEachParameter((parameter) { | 115 signature.forEachParameter((parameter) { |
| 116 parameters_ok = | 116 parameters_ok = |
| 117 parameters_ok && typeVerifier.visit(parameter.type, null); | 117 parameters_ok && typeVerifier.visit(parameter.type, null); |
| 118 }); | 118 }); |
| 119 if (!parameters_ok) return false; | 119 if (!parameters_ok) return false; |
| 120 | 120 |
| 121 // TODO(kmillikin): support getters and setters and static class members. | 121 // TODO(kmillikin): support getters and setters and static class members. |
| 122 // With the current Dart Tree emitter they just require recognizing them | 122 // With the current Dart Tree emitter they just require recognizing them |
| 123 // and generating the correct syntax. | 123 // and generating the correct syntax. |
| 124 if (element.isGetter() || element.isSetter()) return false; | 124 if (element.isGetter || element.isSetter) return false; |
| 125 if (element.enclosingElement.isClass()) return false; | 125 if (element.enclosingElement.isClass) return false; |
| 126 | 126 |
| 127 // TODO(lry): support native functions (also in [visitReturn]). | 127 // TODO(lry): support native functions (also in [visitReturn]). |
| 128 if (function.isNative()) return false; | 128 if (function.isNative) return false; |
| 129 | 129 |
| 130 return true; | 130 return true; |
| 131 } | 131 } |
| 132 | 132 |
| 133 bool get inCheckedMode { | 133 bool get inCheckedMode { |
| 134 bool result = false; | 134 bool result = false; |
| 135 assert((result = true)); | 135 assert((result = true)); |
| 136 return result; | 136 return result; |
| 137 } | 137 } |
| 138 | 138 |
| 139 SourceFile elementSourceFile(Element element) { | 139 SourceFile elementSourceFile(Element element) { |
| 140 if (element is FunctionElement) { | 140 if (element is FunctionElement) { |
| 141 FunctionElement functionElement = element; | 141 FunctionElement functionElement = element; |
| 142 if (functionElement.patch != null) element = functionElement.patch; | 142 if (functionElement.patch != null) element = functionElement.patch; |
| 143 } | 143 } |
| 144 return element.getCompilationUnit().script.file; | 144 return element.compilationUnit.script.file; |
| 145 } | 145 } |
| 146 } | 146 } |
| 147 | 147 |
| 148 /** | 148 /** |
| 149 * A tree visitor that builds [IrNodes]. The visit methods add statements using | 149 * A tree visitor that builds [IrNodes]. The visit methods add statements using |
| 150 * to the [builder] and return the last added statement for trees that represent | 150 * to the [builder] and return the last added statement for trees that represent |
| 151 * an expression. | 151 * an expression. |
| 152 */ | 152 */ |
| 153 class IrBuilder extends ResolvedVisitor<ir.Primitive> { | 153 class IrBuilder extends ResolvedVisitor<ir.Primitive> { |
| 154 final SourceFile sourceFile; | 154 final SourceFile sourceFile; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 * returns `null`. | 231 * returns `null`. |
| 232 */ | 232 */ |
| 233 ir.FunctionDefinition buildFunction(FunctionElement functionElement) { | 233 ir.FunctionDefinition buildFunction(FunctionElement functionElement) { |
| 234 return nullIfGiveup(() => buildFunctionInternal(functionElement)); | 234 return nullIfGiveup(() => buildFunctionInternal(functionElement)); |
| 235 } | 235 } |
| 236 | 236 |
| 237 ir.FunctionDefinition buildFunctionInternal(FunctionElement element) { | 237 ir.FunctionDefinition buildFunctionInternal(FunctionElement element) { |
| 238 assert(invariant(element, element.isImplementation)); | 238 assert(invariant(element, element.isImplementation)); |
| 239 ast.FunctionExpression function = element.parseNode(compiler); | 239 ast.FunctionExpression function = element.parseNode(compiler); |
| 240 assert(function != null); | 240 assert(function != null); |
| 241 assert(!function.modifiers.isExternal()); | 241 assert(!function.modifiers.isExternal); |
| 242 assert(elements[function] != null); | 242 assert(elements[function] != null); |
| 243 | 243 |
| 244 root = current = null; | 244 root = current = null; |
| 245 | 245 |
| 246 FunctionSignature signature = element.functionSignature; | 246 FunctionSignature signature = element.functionSignature; |
| 247 signature.orderedForEachParameter((parameterElement) { | 247 signature.orderedForEachParameter((parameterElement) { |
| 248 ir.Parameter parameter = new ir.Parameter(parameterElement); | 248 ir.Parameter parameter = new ir.Parameter(parameterElement); |
| 249 parameters.add(parameter); | 249 parameters.add(parameter); |
| 250 variableIndex[parameterElement] = assignedVars.length; | 250 variableIndex[parameterElement] = assignedVars.length; |
| 251 assignedVars.add(parameter); | 251 assignedVars.add(parameter); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 assert(isOpen); | 546 assert(isOpen); |
| 547 return giveup(); | 547 return giveup(); |
| 548 } | 548 } |
| 549 | 549 |
| 550 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]] | 550 // Build(StaticSend(f, arguments), C) = C[C'[InvokeStatic(f, xs)]] |
| 551 // where (C', xs) = arguments.fold(Build, C) | 551 // where (C', xs) = arguments.fold(Build, C) |
| 552 ir.Primitive visitStaticSend(ast.Send node) { | 552 ir.Primitive visitStaticSend(ast.Send node) { |
| 553 assert(isOpen); | 553 assert(isOpen); |
| 554 Element element = elements[node]; | 554 Element element = elements[node]; |
| 555 // TODO(lry): support static fields. (separate IR instruction?) | 555 // TODO(lry): support static fields. (separate IR instruction?) |
| 556 if (element.isField() || element.isGetter()) return giveup(); | 556 if (element.isField || element.isGetter) return giveup(); |
| 557 // TODO(kmillikin): support static setters. | 557 // TODO(kmillikin): support static setters. |
| 558 if (element.isSetter()) return giveup(); | 558 if (element.isSetter) return giveup(); |
| 559 // TODO(lry): support constructors / factory calls. | 559 // TODO(lry): support constructors / factory calls. |
| 560 if (element.isConstructor()) return giveup(); | 560 if (element.isConstructor) return giveup(); |
| 561 // TODO(lry): support foreign functions. | 561 // TODO(lry): support foreign functions. |
| 562 if (element.isForeign(compiler)) return giveup(); | 562 if (element.isForeign(compiler)) return giveup(); |
| 563 // TODO(lry): for elements that could not be resolved emit code to throw a | 563 // TODO(lry): for elements that could not be resolved emit code to throw a |
| 564 // [NoSuchMethodError]. | 564 // [NoSuchMethodError]. |
| 565 if (element.isErroneous()) return giveup(); | 565 if (element.isErroneous) return giveup(); |
| 566 // TODO(lry): generate IR for object identicality. | 566 // TODO(lry): generate IR for object identicality. |
| 567 if (element == compiler.identicalFunction) giveup(); | 567 if (element == compiler.identicalFunction) giveup(); |
| 568 | 568 |
| 569 Selector selector = elements.getSelector(node); | 569 Selector selector = elements.getSelector(node); |
| 570 // TODO(lry): support named arguments | 570 // TODO(lry): support named arguments |
| 571 if (selector.namedArgumentCount != 0) return giveup(); | 571 if (selector.namedArgumentCount != 0) return giveup(); |
| 572 | 572 |
| 573 // TODO(kmillikin): support a receiver: A.m(). | 573 // TODO(kmillikin): support a receiver: A.m(). |
| 574 if (node.receiver != null) return giveup(); | 574 if (node.receiver != null) return giveup(); |
| 575 | 575 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 bool visit(DartType type, Null _) => type.accept(this, null); | 636 bool visit(DartType type, Null _) => type.accept(this, null); |
| 637 | 637 |
| 638 bool visitType(DartType type, Null _) => false; | 638 bool visitType(DartType type, Null _) => false; |
| 639 | 639 |
| 640 bool visitVoidType(VoidType type, Null _) => true; | 640 bool visitVoidType(VoidType type, Null _) => true; |
| 641 | 641 |
| 642 // Currently, InterfaceType and TypedefType are supported so long as they | 642 // Currently, InterfaceType and TypedefType are supported so long as they |
| 643 // do not have type parameters. They are subclasses of GenericType. | 643 // do not have type parameters. They are subclasses of GenericType. |
| 644 bool visitGenericType(GenericType type, Null _) => !type.isGeneric; | 644 bool visitGenericType(GenericType type, Null _) => !type.isGeneric; |
| 645 } | 645 } |
| OLD | NEW |