OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
6 | 6 |
7 import '../closure.dart'; | 7 import '../closure.dart'; |
8 import '../common.dart'; | 8 import '../common.dart'; |
9 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 9 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
10 import '../common/names.dart'; | 10 import '../common/names.dart'; |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 if (typeBuilder.checkOrTrustTypes) { | 216 if (typeBuilder.checkOrTrustTypes) { |
217 return typeBuilder.potentiallyCheckOrTrustType( | 217 return typeBuilder.potentiallyCheckOrTrustType( |
218 value, compiler.coreTypes.boolType, | 218 value, compiler.coreTypes.boolType, |
219 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); | 219 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); |
220 } | 220 } |
221 HInstruction result = new HBoolify(value, commonMasks.boolType); | 221 HInstruction result = new HBoolify(value, commonMasks.boolType); |
222 add(result); | 222 add(result); |
223 return result; | 223 return result; |
224 } | 224 } |
225 | 225 |
| 226 void _addClassTypeVariablesIfNeeded(ir.Member constructor) { |
| 227 var enclosing = astAdapter.getElement(constructor).enclosingElement; |
| 228 if (backend.classNeedsRti(enclosing)) { |
| 229 enclosing.typeVariables.forEach((TypeVariableType typeVariable) { |
| 230 HParameterValue param = |
| 231 addParameter(typeVariable.element, commonMasks.nonNullType); |
| 232 localsHandler.directLocals[ |
| 233 localsHandler.getTypeVariableAsLocal(typeVariable)] = param; |
| 234 }); |
| 235 } |
| 236 } |
| 237 |
226 /// Builds generative constructors. | 238 /// Builds generative constructors. |
227 /// | 239 /// |
228 /// Generative constructors are built in two stages. | 240 /// Generative constructors are built in two stages. |
229 /// | 241 /// |
230 /// First, the field values for every instance field for every class in the | 242 /// First, the field values for every instance field for every class in the |
231 /// class hierarchy are collected. Then, create a function body that sets | 243 /// class hierarchy are collected. Then, create a function body that sets |
232 /// all of the instance fields to the collected values and call the | 244 /// all of the instance fields to the collected values and call the |
233 /// constructor bodies for all constructors in the hierarchy. | 245 /// constructor bodies for all constructors in the hierarchy. |
234 void buildConstructor(ir.Constructor constructor) { | 246 void buildConstructor(ir.Constructor constructor) { |
235 openFunction(); | 247 openFunction(); |
| 248 _addClassTypeVariablesIfNeeded(constructor); |
236 | 249 |
237 // Collect field values for the current class. | 250 // Collect field values for the current class. |
238 // TODO(het): Does kernel always put field initializers in the constructor | 251 // TODO(het): Does kernel always put field initializers in the constructor |
239 // initializer list? If so then this is unnecessary... | 252 // initializer list? If so then this is unnecessary... |
240 Map<ir.Field, HInstruction> fieldValues = | 253 Map<ir.Field, HInstruction> fieldValues = |
241 _collectFieldValues(constructor.enclosingClass); | 254 _collectFieldValues(constructor.enclosingClass); |
242 | 255 |
243 _buildInitializers(constructor, fieldValues); | 256 _buildInitializers(constructor, fieldValues); |
244 | 257 |
245 final constructorArguments = <HInstruction>[]; | 258 final constructorArguments = <HInstruction>[]; |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 HInstruction original, DartType type, int kind) { | 405 HInstruction original, DartType type, int kind) { |
393 HInstruction reifiedType = buildFunctionType(type); | 406 HInstruction reifiedType = buildFunctionType(type); |
394 return new HTypeConversion.viaMethodOnType( | 407 return new HTypeConversion.viaMethodOnType( |
395 type, kind, original.instructionType, reifiedType, original); | 408 type, kind, original.instructionType, reifiedType, original); |
396 } | 409 } |
397 | 410 |
398 /// Builds a SSA graph for FunctionNodes, found in FunctionExpressions and | 411 /// Builds a SSA graph for FunctionNodes, found in FunctionExpressions and |
399 /// Procedures. | 412 /// Procedures. |
400 void buildFunctionNode(ir.FunctionNode functionNode) { | 413 void buildFunctionNode(ir.FunctionNode functionNode) { |
401 openFunction(); | 414 openFunction(); |
| 415 if (functionNode.parent is ir.Procedure && |
| 416 (functionNode.parent as ir.Procedure).kind == |
| 417 ir.ProcedureKind.Factory) { |
| 418 _addClassTypeVariablesIfNeeded(functionNode.parent); |
| 419 } |
402 functionNode.body.accept(this); | 420 functionNode.body.accept(this); |
403 closeFunction(); | 421 closeFunction(); |
404 } | 422 } |
405 | 423 |
406 void addImplicitInstantiation(DartType type) { | 424 void addImplicitInstantiation(DartType type) { |
407 if (type != null) { | 425 if (type != null) { |
408 currentImplicitInstantiations.add(type); | 426 currentImplicitInstantiations.add(type); |
409 } | 427 } |
410 } | 428 } |
411 | 429 |
(...skipping 1523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1935 } | 1953 } |
1936 | 1954 |
1937 @override | 1955 @override |
1938 void visitIsExpression(ir.IsExpression isExpression) { | 1956 void visitIsExpression(ir.IsExpression isExpression) { |
1939 isExpression.operand.accept(this); | 1957 isExpression.operand.accept(this); |
1940 HInstruction expression = pop(); | 1958 HInstruction expression = pop(); |
1941 push(buildIsNode(isExpression, isExpression.type, expression)); | 1959 push(buildIsNode(isExpression, isExpression.type, expression)); |
1942 } | 1960 } |
1943 | 1961 |
1944 HInstruction buildIsNode( | 1962 HInstruction buildIsNode( |
1945 ir.Node node, ir.DartType dart_type, HInstruction expression) { | 1963 ir.Node node, ir.DartType type, HInstruction expression) { |
1946 // TODO(sra): Convert the type testing logic here to use ir.DartType. | 1964 // Note: The call to "unalias" this type like in the original SSA builder is |
1947 DartType type = astAdapter.getDartType(dart_type); | 1965 // unnecessary in kernel because Kernel has no notion of typedef. |
1948 | 1966 // TODO(efortuna): Add test for this. |
1949 type = localsHandler.substInContext(type).unaliased; | 1967 DartType typeValue = localsHandler.substInContext( |
1950 | 1968 astAdapter.getDartType(type)); |
1951 if (type is MethodTypeVariableType) { | 1969 if (type is ir.InvalidType) { |
1952 return graph.addConstantBool(true, closedWorld); | 1970 generateTypeError(node, (typeValue.element as ErroneousElement).message); |
| 1971 return new HIs.compound( |
| 1972 typeValue, expression, pop(), commonMasks.boolType); |
1953 } | 1973 } |
1954 | 1974 |
1955 if (type is MalformedType) { | 1975 if (type is ir.FunctionType) { |
1956 ErroneousElement element = type.element; | 1976 List arguments = [buildFunctionType(typeValue), expression]; |
1957 generateTypeError(node, element.message); | 1977 _pushDynamicInvocation(node, null, arguments, |
1958 return new HIs.compound(type, expression, pop(), commonMasks.boolType); | 1978 selector: new Selector.call( |
| 1979 new PrivateName('_isTest', backend.helpers.jsHelperLibrary), |
| 1980 CallStructure.ONE_ARG)); |
| 1981 return new HIs.compound( |
| 1982 typeValue, expression, pop(), commonMasks.boolType); |
1959 } | 1983 } |
1960 | 1984 |
1961 if (type.isFunctionType) { | 1985 if (type is ir.TypeParameterType) { |
1962 List arguments = <HInstruction>[buildFunctionType(type), expression]; | 1986 HInstruction runtimeType = |
1963 _pushDynamicInvocation(node, commonMasks.boolType, arguments, | 1987 typeBuilder.addTypeVariableReference(typeValue, sourceElement); |
1964 selector: new Selector.call( | 1988 _pushStaticInvocation(astAdapter.checkSubtypeOfRuntimeType, |
1965 new PrivateName('_isTest', astAdapter.jsHelperLibrary), | 1989 <HInstruction>[expression, runtimeType], commonMasks.boolType); |
1966 CallStructure.ONE_ARG)); | 1990 return new HIs.variable( |
1967 return new HIs.compound(type, expression, pop(), commonMasks.boolType); | 1991 typeValue, expression, pop(), commonMasks.boolType); |
1968 } | 1992 } |
1969 | 1993 |
1970 if (type.isTypeVariable) { | 1994 if (_isInterfaceWithNoDynamicTypes(type)) { |
1971 HInstruction runtimeType = | 1995 HInstruction representations = typeBuilder |
1972 typeBuilder.addTypeVariableReference(type, sourceElement); | 1996 .buildTypeArgumentRepresentations(typeValue, sourceElement); |
1973 _pushStaticInvocation(astAdapter.checkSubtypeOfRuntimeType, | 1997 add(representations); |
1974 <HInstruction>[expression, runtimeType], commonMasks.boolType); | 1998 ClassElement element = typeValue.element; |
1975 return new HIs.variable(type, expression, pop(), commonMasks.boolType); | 1999 js.Name operator = backend.namer.operatorIs(element); |
| 2000 HInstruction isFieldName = |
| 2001 graph.addConstantStringFromName(operator, closedWorld); |
| 2002 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element) |
| 2003 ? graph.addConstantStringFromName( |
| 2004 backend.namer.substitutionName(element), closedWorld) |
| 2005 : graph.addConstantNull(closedWorld); |
| 2006 List<HInstruction> inputs = <HInstruction>[ |
| 2007 expression, |
| 2008 isFieldName, |
| 2009 representations, |
| 2010 asFieldName |
| 2011 ]; |
| 2012 _pushStaticInvocation( |
| 2013 astAdapter.checkSubtype, inputs, commonMasks.boolType); |
| 2014 return new HIs.compound( |
| 2015 typeValue, expression, pop(), commonMasks.boolType); |
1976 } | 2016 } |
1977 | 2017 |
1978 // TODO(sra): Type with type parameters. | 2018 if (backend.hasDirectCheckFor(typeValue)) { |
| 2019 return new HIs.direct(typeValue, expression, commonMasks.boolType); |
| 2020 } |
| 2021 // The interceptor is not always needed. It is removed by optimization |
| 2022 // when the receiver type or tested type permit. |
| 2023 return new HIs.raw(typeValue, expression, _interceptorFor(expression), |
| 2024 commonMasks.boolType); |
| 2025 } |
1979 | 2026 |
1980 if (backend.hasDirectCheckFor(type)) { | 2027 bool _isInterfaceWithNoDynamicTypes(ir.DartType type) { |
1981 return new HIs.direct(type, expression, commonMasks.boolType); | 2028 bool isMethodTypeVariableType(ir.DartType typeArgType) { |
| 2029 return (typeArgType is ir.TypeParameterType && |
| 2030 typeArgType.parameter.parent is ir.FunctionNode); |
1982 } | 2031 } |
1983 | 2032 |
1984 // The interceptor is not always needed. It is removed by optimization | 2033 return type is ir.InterfaceType && |
1985 // when the receiver type or tested type permit. | 2034 (type as ir.InterfaceType).typeArguments.any( |
1986 HInterceptor interceptor = _interceptorFor(expression); | 2035 (ir.DartType typeArgType) => |
1987 return new HIs.raw(type, expression, interceptor, commonMasks.boolType); | 2036 typeArgType is! ir.DynamicType && |
| 2037 typeArgType is! ir.InvalidType && |
| 2038 !isMethodTypeVariableType(type)); |
1988 } | 2039 } |
1989 | 2040 |
1990 @override | 2041 @override |
1991 void visitThrow(ir.Throw throwNode) { | 2042 void visitThrow(ir.Throw throwNode) { |
1992 _visitThrowExpression(throwNode.expression); | 2043 _visitThrowExpression(throwNode.expression); |
1993 if (isReachable) { | 2044 if (isReachable) { |
1994 push(new HThrowExpression(pop(), null)); | 2045 push(new HThrowExpression(pop(), null)); |
1995 isReachable = false; | 2046 isReachable = false; |
1996 } | 2047 } |
1997 } | 2048 } |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2279 kernelBuilder.open(exitBlock); | 2330 kernelBuilder.open(exitBlock); |
2280 enterBlock.setBlockFlow( | 2331 enterBlock.setBlockFlow( |
2281 new HTryBlockInformation( | 2332 new HTryBlockInformation( |
2282 kernelBuilder.wrapStatementGraph(bodyGraph), | 2333 kernelBuilder.wrapStatementGraph(bodyGraph), |
2283 exception, | 2334 exception, |
2284 kernelBuilder.wrapStatementGraph(catchGraph), | 2335 kernelBuilder.wrapStatementGraph(catchGraph), |
2285 kernelBuilder.wrapStatementGraph(finallyGraph)), | 2336 kernelBuilder.wrapStatementGraph(finallyGraph)), |
2286 exitBlock); | 2337 exitBlock); |
2287 } | 2338 } |
2288 } | 2339 } |
OLD | NEW |