OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of ssa; | 5 part of ssa; |
6 | 6 |
7 class SsaFunctionCompiler implements FunctionCompiler { | 7 class SsaFunctionCompiler implements FunctionCompiler { |
8 SsaCodeGeneratorTask generator; | 8 SsaCodeGeneratorTask generator; |
9 SsaBuilderTask builder; | 9 SsaBuilderTask builder; |
10 SsaOptimizerTask optimizer; | 10 SsaOptimizerTask optimizer; |
(...skipping 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1051 * Variables stored in the current activation. These variables are | 1051 * Variables stored in the current activation. These variables are |
1052 * being updated in try/catch blocks, and should be | 1052 * being updated in try/catch blocks, and should be |
1053 * accessed indirectly through [HLocalGet] and [HLocalSet]. | 1053 * accessed indirectly through [HLocalGet] and [HLocalSet]. |
1054 */ | 1054 */ |
1055 Map<Local, HLocalValue> activationVariables = | 1055 Map<Local, HLocalValue> activationVariables = |
1056 <Local, HLocalValue>{}; | 1056 <Local, HLocalValue>{}; |
1057 | 1057 |
1058 // We build the Ssa graph by simulating a stack machine. | 1058 // We build the Ssa graph by simulating a stack machine. |
1059 List<HInstruction> stack = <HInstruction>[]; | 1059 List<HInstruction> stack = <HInstruction>[]; |
1060 | 1060 |
1061 /// Returns `true` if the current element is an `async` function. | |
1062 bool get isAsync { | |
floitsch
2015/02/11 15:04:13
This would mean that the "SsaBuilder".isAsync.
Ei
sigurdm
2015/02/12 09:36:48
Done.
| |
1063 Element element = sourceElement; | |
1064 return (element is FunctionElement && | |
1065 element.asyncMarker == AsyncMarker.ASYNC); | |
1066 } | |
1067 | |
1061 SsaBuilder(JavaScriptBackend backend, | 1068 SsaBuilder(JavaScriptBackend backend, |
1062 CodegenWorkItem work, | 1069 CodegenWorkItem work, |
1063 this.nativeEmitter, | 1070 this.nativeEmitter, |
1064 this.generateSourceMap) | 1071 this.generateSourceMap) |
1065 : this.compiler = backend.compiler, | 1072 : this.compiler = backend.compiler, |
1066 this.backend = backend, | 1073 this.backend = backend, |
1067 this.constantSystem = backend.constantSystem, | 1074 this.constantSystem = backend.constantSystem, |
1068 this.work = work, | 1075 this.work = work, |
1069 this.rti = backend.rti, | 1076 this.rti = backend.rti, |
1070 super(work.resolutionTree) { | 1077 super(work.resolutionTree) { |
(...skipping 4101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5172 targetType = localsHandler.substInContext(targetType); | 5179 targetType = localsHandler.substInContext(targetType); |
5173 targetType.typeArguments.forEach((DartType argument) { | 5180 targetType.typeArguments.forEach((DartType argument) { |
5174 inputs.add(analyzeTypeArgument(argument)); | 5181 inputs.add(analyzeTypeArgument(argument)); |
5175 }); | 5182 }); |
5176 } | 5183 } |
5177 pushInvokeStatic(node, targetConstructor, inputs); | 5184 pushInvokeStatic(node, targetConstructor, inputs); |
5178 HInstruction value = pop(); | 5185 HInstruction value = pop(); |
5179 emitReturn(value, node); | 5186 emitReturn(value, node); |
5180 } | 5187 } |
5181 | 5188 |
5189 /// Returns `true` if [Future] is a [type]. | |
floitsch
2015/02/11 15:04:13
/// Returns true if the [type] is a valid return t
sigurdm
2015/02/12 09:36:48
Done.
| |
5190 bool isValidAsyncReturnType(type) { | |
floitsch
2015/02/11 15:04:13
Argument type is missing.
sigurdm
2015/02/12 09:36:48
Done.
| |
5191 assert (isAsync); | |
5192 // TODO(sigurdm): In an internal library a function could be declared: | |
5193 // | |
5194 // _FutureImpl foo async => 1; | |
5195 // | |
5196 // This should be valid (because the actual value returned from an async | |
5197 // function is a `_FutureImpl`), but currently false is returned in this | |
5198 // case. | |
5199 return type.isDynamic || | |
5200 type.isObject || | |
5201 (type is InterfaceType && | |
5202 type.element == compiler.futureClass); | |
5203 } | |
5204 | |
5182 visitReturn(ast.Return node) { | 5205 visitReturn(ast.Return node) { |
5183 if (identical(node.beginToken.stringValue, 'native')) { | 5206 if (identical(node.beginToken.stringValue, 'native')) { |
5184 native.handleSsaNative(this, node.expression); | 5207 native.handleSsaNative(this, node.expression); |
5185 return; | 5208 return; |
5186 } | 5209 } |
5187 HInstruction value; | 5210 HInstruction value; |
5188 if (node.expression == null) { | 5211 if (node.expression == null) { |
5189 value = graph.addConstantNull(compiler); | 5212 value = graph.addConstantNull(compiler); |
5190 } else { | 5213 } else { |
5191 visit(node.expression); | 5214 visit(node.expression); |
5192 value = pop(); | 5215 value = pop(); |
5193 value = potentiallyCheckOrTrustType(value, returnType); | 5216 if (isAsync) { |
5217 if (compiler.enableTypeAssertions && | |
5218 !isValidAsyncReturnType(returnType)) { | |
5219 String message = | |
5220 "Async function returned a Future, " | |
5221 "was declared to return a $returnType."; | |
5222 generateTypeError(node, message); | |
5223 pop(); | |
5224 return; | |
5225 } | |
5226 } else { | |
5227 value = potentiallyCheckOrTrustType(value, returnType); | |
5228 } | |
5194 } | 5229 } |
5195 | 5230 |
5196 handleInTryStatement(); | 5231 handleInTryStatement(); |
5197 emitReturn(value, node); | 5232 emitReturn(value, node); |
5198 } | 5233 } |
5199 | 5234 |
5200 visitThrow(ast.Throw node) { | 5235 visitThrow(ast.Throw node) { |
5201 visitThrowExpression(node.expression); | 5236 visitThrowExpression(node.expression); |
5202 if (isReachable) { | 5237 if (isReachable) { |
5203 handleInTryStatement(); | 5238 handleInTryStatement(); |
(...skipping 1670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6874 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 6909 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
6875 unaliased.accept(this, builder); | 6910 unaliased.accept(this, builder); |
6876 } | 6911 } |
6877 | 6912 |
6878 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 6913 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
6879 JavaScriptBackend backend = builder.compiler.backend; | 6914 JavaScriptBackend backend = builder.compiler.backend; |
6880 ClassElement cls = backend.findHelper('DynamicRuntimeType'); | 6915 ClassElement cls = backend.findHelper('DynamicRuntimeType'); |
6881 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 6916 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
6882 } | 6917 } |
6883 } | 6918 } |
OLD | NEW |