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 DartType typeValue = localsHandler.substInContext( |
1947 DartType type = astAdapter.getDartType(dart_type); | 1965 astAdapter.getDartType(type)); |
Siggi Cherem (dart-lang)
2016/12/22 19:40:37
just wondering, do we want to mention that we don'
Emily Fortuna
2016/12/22 19:52:43
Done.
| |
1948 | 1966 if (type is ir.InvalidType) { |
1949 type = localsHandler.substInContext(type).unaliased; | 1967 generateTypeError(node, (typeValue.element as ErroneousElement).message); |
1950 | 1968 return new HIs.compound( |
1951 if (type is MethodTypeVariableType) { | 1969 typeValue, expression, pop(), commonMasks.boolType); |
1952 return graph.addConstantBool(true, closedWorld); | |
1953 } | 1970 } |
1954 | 1971 |
1955 if (type is MalformedType) { | 1972 if (type is ir.FunctionType) { |
1956 ErroneousElement element = type.element; | 1973 List arguments = [buildFunctionType(typeValue), expression]; |
1957 generateTypeError(node, element.message); | 1974 _pushDynamicInvocation(node, null, arguments, |
1958 return new HIs.compound(type, expression, pop(), commonMasks.boolType); | 1975 selector: new Selector.call( |
1976 new PrivateName('_isTest', backend.helpers.jsHelperLibrary), | |
1977 CallStructure.ONE_ARG)); | |
1978 return new HIs.compound( | |
1979 typeValue, expression, pop(), commonMasks.boolType); | |
1959 } | 1980 } |
1960 | 1981 |
1961 if (type.isFunctionType) { | 1982 if (type is ir.TypeParameterType) { |
1962 List arguments = <HInstruction>[buildFunctionType(type), expression]; | 1983 HInstruction runtimeType = |
1963 _pushDynamicInvocation(node, commonMasks.boolType, arguments, | 1984 typeBuilder.addTypeVariableReference(typeValue, sourceElement); |
1964 selector: new Selector.call( | 1985 _pushStaticInvocation(astAdapter.checkSubtypeOfRuntimeType, |
1965 new PrivateName('_isTest', astAdapter.jsHelperLibrary), | 1986 <HInstruction>[expression, runtimeType], commonMasks.boolType); |
1966 CallStructure.ONE_ARG)); | 1987 return new HIs.variable( |
1967 return new HIs.compound(type, expression, pop(), commonMasks.boolType); | 1988 typeValue, expression, pop(), commonMasks.boolType); |
1968 } | 1989 } |
1969 | 1990 |
1970 if (type.isTypeVariable) { | 1991 if (_isInterfaceWithNoDynamicTypes(type)) { |
1971 HInstruction runtimeType = | 1992 HInstruction representations = typeBuilder |
1972 typeBuilder.addTypeVariableReference(type, sourceElement); | 1993 .buildTypeArgumentRepresentations(typeValue, sourceElement); |
1973 _pushStaticInvocation(astAdapter.checkSubtypeOfRuntimeType, | 1994 add(representations); |
1974 <HInstruction>[expression, runtimeType], commonMasks.boolType); | 1995 ClassElement element = typeValue.element; |
1975 return new HIs.variable(type, expression, pop(), commonMasks.boolType); | 1996 js.Name operator = backend.namer.operatorIs(element); |
1997 HInstruction isFieldName = | |
1998 graph.addConstantStringFromName(operator, closedWorld); | |
1999 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element) | |
2000 ? graph.addConstantStringFromName( | |
2001 backend.namer.substitutionName(element), closedWorld) | |
2002 : graph.addConstantNull(closedWorld); | |
2003 List<HInstruction> inputs = <HInstruction>[ | |
2004 expression, | |
2005 isFieldName, | |
2006 representations, | |
2007 asFieldName | |
2008 ]; | |
2009 _pushStaticInvocation( | |
2010 astAdapter.checkSubtype, inputs, commonMasks.boolType); | |
2011 return new HIs.compound( | |
2012 typeValue, expression, pop(), commonMasks.boolType); | |
1976 } | 2013 } |
1977 | 2014 |
1978 // TODO(sra): Type with type parameters. | 2015 if (backend.hasDirectCheckFor(typeValue)) { |
2016 return new HIs.direct(typeValue, expression, commonMasks.boolType); | |
2017 } | |
2018 // The interceptor is not always needed. It is removed by optimization | |
2019 // when the receiver type or tested type permit. | |
2020 return new HIs.raw(typeValue, expression, _interceptorFor(expression), | |
2021 commonMasks.boolType); | |
2022 } | |
1979 | 2023 |
1980 if (backend.hasDirectCheckFor(type)) { | 2024 bool _isInterfaceWithNoDynamicTypes(ir.DartType type) { |
1981 return new HIs.direct(type, expression, commonMasks.boolType); | 2025 bool isMethodTypeVariableType(ir.DartType typeArgType) { |
2026 return (typeArgType is ir.TypeParameterType && | |
2027 (typeArgType as ir.TypeParameterType).parameter.parent | |
Siggi Cherem (dart-lang)
2016/12/22 19:40:37
remove cast -- type promotion makes it unnecessary
Emily Fortuna
2016/12/22 19:52:43
Done.
| |
2028 is ir.FunctionNode); | |
1982 } | 2029 } |
1983 | 2030 |
1984 // The interceptor is not always needed. It is removed by optimization | 2031 return type is ir.InterfaceType && |
1985 // when the receiver type or tested type permit. | 2032 (type as ir.InterfaceType).typeArguments.any( |
1986 HInterceptor interceptor = _interceptorFor(expression); | 2033 (ir.DartType typeArgType) => |
1987 return new HIs.raw(type, expression, interceptor, commonMasks.boolType); | 2034 typeArgType is! ir.DynamicType && |
2035 typeArgType is! ir.InvalidType && | |
2036 !isMethodTypeVariableType(type)); | |
1988 } | 2037 } |
1989 | 2038 |
1990 @override | 2039 @override |
1991 void visitThrow(ir.Throw throwNode) { | 2040 void visitThrow(ir.Throw throwNode) { |
1992 _visitThrowExpression(throwNode.expression); | 2041 _visitThrowExpression(throwNode.expression); |
1993 if (isReachable) { | 2042 if (isReachable) { |
1994 push(new HThrowExpression(pop(), null)); | 2043 push(new HThrowExpression(pop(), null)); |
1995 isReachable = false; | 2044 isReachable = false; |
1996 } | 2045 } |
1997 } | 2046 } |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2279 kernelBuilder.open(exitBlock); | 2328 kernelBuilder.open(exitBlock); |
2280 enterBlock.setBlockFlow( | 2329 enterBlock.setBlockFlow( |
2281 new HTryBlockInformation( | 2330 new HTryBlockInformation( |
2282 kernelBuilder.wrapStatementGraph(bodyGraph), | 2331 kernelBuilder.wrapStatementGraph(bodyGraph), |
2283 exception, | 2332 exception, |
2284 kernelBuilder.wrapStatementGraph(catchGraph), | 2333 kernelBuilder.wrapStatementGraph(catchGraph), |
2285 kernelBuilder.wrapStatementGraph(finallyGraph)), | 2334 kernelBuilder.wrapStatementGraph(finallyGraph)), |
2286 exitBlock); | 2335 exitBlock); |
2287 } | 2336 } |
2288 } | 2337 } |
OLD | NEW |