| 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'; | 7 import 'ir_nodes.dart'; |
| 8 import '../elements/elements.dart'; | 8 import '../elements/elements.dart'; |
| 9 import '../elements/modelx.dart' show FunctionElementX; | 9 import '../elements/modelx.dart' show FunctionElementX; |
| 10 import '../dart2jslib.dart'; | 10 import '../dart2jslib.dart'; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 LibraryElement library = element.declaration.getLibrary(); | 76 LibraryElement library = element.declaration.getLibrary(); |
| 77 IrConstantPool constantPool = IrConstantPool.forLibrary(library); | 77 IrConstantPool constantPool = IrConstantPool.forLibrary(library); |
| 78 List<int> data = irNode.pickle(constantPool); | 78 List<int> data = irNode.pickle(constantPool); |
| 79 irNode = new Unpickler(compiler, constantPool).unpickle(data); | 79 irNode = new Unpickler(compiler, constantPool).unpickle(data); |
| 80 return true; | 80 return true; |
| 81 }); | 81 }); |
| 82 nodes[element] = irNode; | 82 nodes[element] = irNode; |
| 83 unlinkTreeAndToken(element); | 83 unlinkTreeAndToken(element); |
| 84 } | 84 } |
| 85 } | 85 } |
| 86 ensureIr(element); |
| 86 }); | 87 }); |
| 87 }); | 88 }); |
| 88 } | 89 } |
| 89 | 90 |
| 90 bool irEnabled() { | 91 bool irEnabled() { |
| 91 // TODO(lry): support checked-mode checks. | 92 // TODO(lry): support checked-mode checks. |
| 92 if (compiler.enableTypeAssertions || | 93 if (compiler.enableTypeAssertions || |
| 93 compiler.backend is !JavaScriptBackend || | 94 compiler.backend is !JavaScriptBackend || |
| 94 compiler.enableConcreteTypeInference) { | 95 compiler.enableConcreteTypeInference) { |
| 95 return false; | 96 return false; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 107 if (signature.parameterCount > 0) return false; | 108 if (signature.parameterCount > 0) return false; |
| 108 | 109 |
| 109 // TODO(lry): support intercepted methods. Then the dependency on | 110 // TODO(lry): support intercepted methods. Then the dependency on |
| 110 // JavaScriptBackend will go away. | 111 // JavaScriptBackend will go away. |
| 111 JavaScriptBackend backend = compiler.backend; | 112 JavaScriptBackend backend = compiler.backend; |
| 112 if (backend.isInterceptedMethod(element)) return false; | 113 if (backend.isInterceptedMethod(element)) return false; |
| 113 | 114 |
| 114 // TODO(lry): support native functions (also in [visitReturn]). | 115 // TODO(lry): support native functions (also in [visitReturn]). |
| 115 if (function.isNative()) return false; | 116 if (function.isNative()) return false; |
| 116 | 117 |
| 118 // Methods annotated @IrRepresentation(false). |
| 119 if (enforceAstRepresentation(function)) return false; |
| 120 |
| 117 return true; | 121 return true; |
| 118 } | 122 } |
| 119 | 123 |
| 124 bool get inCheckedMode { |
| 125 bool result = false; |
| 126 assert((result = true)); |
| 127 return result; |
| 128 } |
| 129 |
| 130 bool enforceAstRepresentation(Element element) { |
| 131 return irRepresentationValue(element, false); |
| 132 } |
| 133 |
| 134 bool enforceIrRepresentation(Element element) { |
| 135 return irRepresentationValue(element, true); |
| 136 } |
| 137 |
| 138 /** |
| 139 * In host-checked mode, the @IrRepresentation annotation can be used to |
| 140 * enforce the internal representation of a function. |
| 141 */ |
| 142 bool irRepresentationValue(Element element, bool expected) { |
| 143 if (!inCheckedMode || compiler.backend is !JavaScriptBackend) return false; |
| 144 JavaScriptBackend backend = compiler.backend; |
| 145 for (MetadataAnnotation metadata in element.metadata) { |
| 146 if (!metadata.value.isConstructedObject()) continue; |
| 147 ObjectConstant value = metadata.value; |
| 148 ClassElement cls = value.type.element; |
| 149 if (cls == backend.irRepresentationClass) { |
| 150 ConstructedConstant classConstant = value; |
| 151 BoolConstant constant = classConstant.fields[0]; |
| 152 return constant.value == expected; |
| 153 } |
| 154 } |
| 155 return false; |
| 156 } |
| 157 |
| 158 void ensureIr(Element element) { |
| 159 // If no IR was built for [element], ensure it is not annotated |
| 160 // @IrRepresentation(true). |
| 161 if (inCheckedMode && |
| 162 !compiler.irBuilder.hasIr(element) && |
| 163 enforceIrRepresentation(element)) { |
| 164 compiler.reportFatalError( |
| 165 element, |
| 166 MessageKind.GENERIC, |
| 167 {'text': "Error: cannot build IR for $element."}); |
| 168 } |
| 169 } |
| 170 |
| 120 void unlinkTreeAndToken(element) { | 171 void unlinkTreeAndToken(element) { |
| 121 // Ensure the function signature has been computed (requires the AST). | 172 // Ensure the function signature has been computed (requires the AST). |
| 122 assert(element is !FunctionElementX || element.functionSignature != null); | 173 assert(element is !FunctionElementX || element.functionSignature != null); |
| 123 bool isCheckedMode = false; | 174 if (inCheckedMode) { |
| 124 assert((isCheckedMode = true)); | |
| 125 if (isCheckedMode) { | |
| 126 element.beginToken.next = null; | 175 element.beginToken.next = null; |
| 127 element.cachedNode = null; | 176 element.cachedNode = null; |
| 128 } | 177 } |
| 129 } | 178 } |
| 130 | 179 |
| 131 SourceFile elementSourceFile(Element element) { | 180 SourceFile elementSourceFile(Element element) { |
| 132 if (element is FunctionElement) { | 181 if (element is FunctionElement) { |
| 133 FunctionElement functionElement = element; | 182 FunctionElement functionElement = element; |
| 134 if (functionElement.patch != null) element = functionElement.patch; | 183 if (functionElement.patch != null) element = functionElement.patch; |
| 135 } | 184 } |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 | 412 |
| 364 void exitBlock() { | 413 void exitBlock() { |
| 365 blockBuilders.removeLast(); | 414 blockBuilders.removeLast(); |
| 366 } | 415 } |
| 367 } | 416 } |
| 368 | 417 |
| 369 class BlockBuilder { | 418 class BlockBuilder { |
| 370 List<IrNode> statements = <IrNode>[]; | 419 List<IrNode> statements = <IrNode>[]; |
| 371 bool hasReturn = false; | 420 bool hasReturn = false; |
| 372 } | 421 } |
| OLD | NEW |