Chromium Code Reviews| 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 |