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 final SsaCodeGeneratorTask generator; | 8 final SsaCodeGeneratorTask generator; |
9 final SsaBuilderTask builder; | 9 final SsaBuilderTask builder; |
10 final SsaOptimizerTask optimizer; | 10 final SsaOptimizerTask optimizer; |
(...skipping 7132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7143 } | 7143 } |
7144 | 7144 |
7145 visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { | 7145 visitRedirectingFactoryBody(ast.RedirectingFactoryBody node) { |
7146 ConstructorElement targetConstructor = | 7146 ConstructorElement targetConstructor = |
7147 elements.getRedirectingTargetConstructor(node).implementation; | 7147 elements.getRedirectingTargetConstructor(node).implementation; |
7148 ConstructorElement redirectingConstructor = sourceElement.implementation; | 7148 ConstructorElement redirectingConstructor = sourceElement.implementation; |
7149 List<HInstruction> inputs = <HInstruction>[]; | 7149 List<HInstruction> inputs = <HInstruction>[]; |
7150 FunctionSignature targetSignature = targetConstructor.functionSignature; | 7150 FunctionSignature targetSignature = targetConstructor.functionSignature; |
7151 FunctionSignature redirectingSignature = | 7151 FunctionSignature redirectingSignature = |
7152 redirectingConstructor.functionSignature; | 7152 redirectingConstructor.functionSignature; |
7153 redirectingSignature.forEachRequiredParameter((ParameterElement element) { | 7153 |
7154 inputs.add(localsHandler.readLocal(element)); | 7154 List<Element> targetRequireds = targetSignature.requiredParameters; |
7155 }); | 7155 List<Element> redirectingRequireds |
| 7156 = redirectingSignature.requiredParameters; |
| 7157 |
7156 List<Element> targetOptionals = | 7158 List<Element> targetOptionals = |
7157 targetSignature.orderedOptionalParameters; | 7159 targetSignature.orderedOptionalParameters; |
7158 List<Element> redirectingOptionals = | 7160 List<Element> redirectingOptionals = |
7159 redirectingSignature.orderedOptionalParameters; | 7161 redirectingSignature.orderedOptionalParameters; |
7160 int i = 0; | 7162 |
7161 for (; i < redirectingOptionals.length; i++) { | 7163 // TODO(25579): This code can do the wrong thing redirecting constructor and |
7162 ParameterElement parameter = redirectingOptionals[i]; | 7164 // the target do not correspond. It is correct if there is no |
| 7165 // warning. Ideally the redirecting constructor and the target would be the |
| 7166 // same function. |
| 7167 |
| 7168 void loadLocal(ParameterElement parameter) { |
7163 inputs.add(localsHandler.readLocal(parameter)); | 7169 inputs.add(localsHandler.readLocal(parameter)); |
7164 } | 7170 } |
7165 for (; i < targetOptionals.length; i++) { | 7171 void loadPosition(int position, ParameterElement optionalParameter) { |
7166 inputs.add(handleConstantForOptionalParameter(targetOptionals[i])); | 7172 if (position < redirectingRequireds.length) { |
| 7173 loadLocal(redirectingRequireds[position]); |
| 7174 } else if (position < redirectingSignature.parameterCount && |
| 7175 !redirectingSignature.optionalParametersAreNamed) { |
| 7176 loadLocal(redirectingOptionals[position - redirectingRequireds.length]); |
| 7177 } else if (optionalParameter != null) { |
| 7178 inputs.add(handleConstantForOptionalParameter(optionalParameter)); |
| 7179 } else { |
| 7180 // Wrong. |
| 7181 inputs.add(graph.addConstantNull(compiler)); |
| 7182 } |
7167 } | 7183 } |
| 7184 |
| 7185 int position = 0; |
| 7186 |
| 7187 for (ParameterElement targetParameter in targetRequireds) { |
| 7188 loadPosition(position++, null); |
| 7189 } |
| 7190 |
| 7191 if (targetOptionals.isNotEmpty) { |
| 7192 if (targetSignature.optionalParametersAreNamed) { |
| 7193 for (ParameterElement parameter in targetOptionals) { |
| 7194 ParameterElement redirectingParameter = |
| 7195 redirectingOptionals.firstWhere( |
| 7196 (p) => p.name == parameter.name, |
| 7197 orElse: () => null); |
| 7198 if (redirectingParameter == null) { |
| 7199 inputs.add(handleConstantForOptionalParameter(parameter)); |
| 7200 } else { |
| 7201 inputs.add(localsHandler.readLocal(redirectingParameter)); |
| 7202 } |
| 7203 } |
| 7204 } else { |
| 7205 for (ParameterElement parameter in targetOptionals) { |
| 7206 loadPosition(position++, parameter); |
| 7207 } |
| 7208 } |
| 7209 } |
| 7210 |
7168 ClassElement targetClass = targetConstructor.enclosingClass; | 7211 ClassElement targetClass = targetConstructor.enclosingClass; |
7169 if (backend.classNeedsRti(targetClass)) { | 7212 if (backend.classNeedsRti(targetClass)) { |
7170 ClassElement cls = redirectingConstructor.enclosingClass; | 7213 ClassElement cls = redirectingConstructor.enclosingClass; |
7171 InterfaceType targetType = | 7214 InterfaceType targetType = |
7172 redirectingConstructor.computeEffectiveTargetType(cls.thisType); | 7215 redirectingConstructor.computeEffectiveTargetType(cls.thisType); |
7173 targetType = localsHandler.substInContext(targetType); | 7216 targetType = localsHandler.substInContext(targetType); |
7174 targetType.typeArguments.forEach((DartType argument) { | 7217 targetType.typeArguments.forEach((DartType argument) { |
7175 inputs.add(analyzeTypeArgument(argument)); | 7218 inputs.add(analyzeTypeArgument(argument)); |
7176 }); | 7219 }); |
7177 } | 7220 } |
(...skipping 2008 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9186 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 9229 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
9187 unaliased.accept(this, builder); | 9230 unaliased.accept(this, builder); |
9188 } | 9231 } |
9189 | 9232 |
9190 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 9233 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
9191 JavaScriptBackend backend = builder.compiler.backend; | 9234 JavaScriptBackend backend = builder.compiler.backend; |
9192 ClassElement cls = backend.helpers.DynamicRuntimeType; | 9235 ClassElement cls = backend.helpers.DynamicRuntimeType; |
9193 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); | 9236 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); |
9194 } | 9237 } |
9195 } | 9238 } |
OLD | NEW |