Chromium Code Reviews| 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 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 191 assert(graph.isValid()); | 191 assert(graph.isValid()); |
| 192 return graph; | 192 return graph; |
| 193 } | 193 } |
| 194 | 194 |
| 195 void buildField(ir.Field field) { | 195 void buildField(ir.Field field) { |
| 196 openFunction(); | 196 openFunction(); |
| 197 if (field.initializer != null) { | 197 if (field.initializer != null) { |
| 198 field.initializer.accept(this); | 198 field.initializer.accept(this); |
| 199 HInstruction fieldValue = pop(); | 199 HInstruction fieldValue = pop(); |
| 200 HInstruction checkInstruction = typeBuilder.potentiallyCheckOrTrustType( | 200 HInstruction checkInstruction = typeBuilder.potentiallyCheckOrTrustType( |
| 201 fieldValue, astAdapter.getDartType(field.type)); | 201 fieldValue, astAdapter.getDartTypeInvalidNull(field.type)); |
| 202 stack.add(checkInstruction); | 202 stack.add(checkInstruction); |
| 203 } else { | 203 } else { |
| 204 stack.add(graph.addConstantNull(closedWorld)); | 204 stack.add(graph.addConstantNull(closedWorld)); |
| 205 } | 205 } |
| 206 HInstruction value = pop(); | 206 HInstruction value = pop(); |
| 207 closeAndGotoExit(new HReturn(value, null)); | 207 closeAndGotoExit(new HReturn(value, null)); |
| 208 closeFunction(); | 208 closeFunction(); |
| 209 } | 209 } |
| 210 | 210 |
| 211 /// Pops the most recent instruction from the stack and 'boolifies' it. | 211 /// Pops the most recent instruction from the stack and 'boolifies' it. |
| (...skipping 743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 955 handleIf( | 955 handleIf( |
| 956 visitCondition: () => ifStatement.condition.accept(this), | 956 visitCondition: () => ifStatement.condition.accept(this), |
| 957 visitThen: () => ifStatement.then.accept(this), | 957 visitThen: () => ifStatement.then.accept(this), |
| 958 visitElse: () => ifStatement.otherwise?.accept(this)); | 958 visitElse: () => ifStatement.otherwise?.accept(this)); |
| 959 } | 959 } |
| 960 | 960 |
| 961 @override | 961 @override |
| 962 void visitAsExpression(ir.AsExpression asExpression) { | 962 void visitAsExpression(ir.AsExpression asExpression) { |
| 963 asExpression.operand.accept(this); | 963 asExpression.operand.accept(this); |
| 964 HInstruction expressionInstruction = pop(); | 964 HInstruction expressionInstruction = pop(); |
| 965 | |
| 966 if (asExpression.type is ir.InvalidType) { | |
| 967 generateTypeError(asExpression, 'invalid type'); | |
| 968 stack.add(expressionInstruction); | |
| 969 return; | |
| 970 } | |
| 971 | |
| 965 ResolutionDartType type = astAdapter.getDartType(asExpression.type); | 972 ResolutionDartType type = astAdapter.getDartType(asExpression.type); |
| 966 if (type.isMalformed) { | 973 if (type.isMalformed) { |
| 967 if (type is MalformedType) { | 974 if (type is MalformedType) { |
| 968 ErroneousElement element = type.element; | 975 ErroneousElement element = type.element; |
| 969 generateTypeError(asExpression, element.message); | 976 generateTypeError(asExpression, element.message); |
| 970 } else { | 977 } else { |
| 971 assert(type is MethodTypeVariableType); | 978 assert(type is MethodTypeVariableType); |
| 972 stack.add(expressionInstruction); | 979 stack.add(expressionInstruction); |
| 973 } | 980 } |
| 974 } else { | 981 } else { |
| 975 HInstruction converted = typeBuilder.buildTypeConversion( | 982 HInstruction converted = typeBuilder.buildTypeConversion( |
| 976 expressionInstruction, | 983 expressionInstruction, |
| 977 localsHandler.substInContext(type), | 984 localsHandler.substInContext(type), |
| 978 HTypeConversion.CAST_TYPE_CHECK); | 985 HTypeConversion.CAST_TYPE_CHECK); |
| 979 if (converted != expressionInstruction) { | 986 if (converted != expressionInstruction) { |
| 980 add(converted); | 987 add(converted); |
| 981 } | 988 } |
| 982 stack.add(converted); | 989 stack.add(converted); |
| 983 } | 990 } |
| 984 } | 991 } |
| 985 | 992 |
| 986 void generateError(ir.Node node, String message, TypeMask typeMask) { | 993 void generateError( |
| 994 ir.Node node, ir.Procedure procedure, String message, TypeMask typeMask) { | |
| 987 HInstruction errorMessage = | 995 HInstruction errorMessage = |
| 988 graph.addConstantString(new DartString.literal(message), closedWorld); | 996 graph.addConstantString(new DartString.literal(message), closedWorld); |
| 989 _pushStaticInvocation(node, [errorMessage], typeMask); | 997 // TODO(sra): Assocate source info from [node]. |
| 998 _pushStaticInvocation(procedure, [errorMessage], typeMask); | |
| 990 } | 999 } |
| 991 | 1000 |
| 992 void generateTypeError(ir.Node node, String message) { | 1001 void generateTypeError(ir.Node node, String message) { |
| 993 generateError(node, message, astAdapter.throwTypeErrorType); | 1002 generateError(node, astAdapter.throwTypeError, message, |
| 1003 astAdapter.throwTypeErrorType); | |
| 994 } | 1004 } |
| 995 | 1005 |
| 996 @override | 1006 @override |
| 997 void visitAssertStatement(ir.AssertStatement assertStatement) { | 1007 void visitAssertStatement(ir.AssertStatement assertStatement) { |
| 998 if (!compiler.options.enableUserAssertions) return; | 1008 if (!compiler.options.enableUserAssertions) return; |
| 999 if (assertStatement.message == null) { | 1009 if (assertStatement.message == null) { |
| 1000 assertStatement.condition.accept(this); | 1010 assertStatement.condition.accept(this); |
| 1001 _pushStaticInvocation(astAdapter.assertHelper, <HInstruction>[pop()], | 1011 _pushStaticInvocation(astAdapter.assertHelper, <HInstruction>[pop()], |
| 1002 astAdapter.assertHelperReturnType); | 1012 astAdapter.assertHelperReturnType); |
| 1003 pop(); | 1013 pop(); |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1313 | 1323 |
| 1314 var staticTarget = staticSet.target; | 1324 var staticTarget = staticSet.target; |
| 1315 if (staticTarget is ir.Procedure) { | 1325 if (staticTarget is ir.Procedure) { |
| 1316 // Invoke the setter | 1326 // Invoke the setter |
| 1317 _pushStaticInvocation(staticTarget, <HInstruction>[value], | 1327 _pushStaticInvocation(staticTarget, <HInstruction>[value], |
| 1318 astAdapter.returnTypeOf(staticTarget)); | 1328 astAdapter.returnTypeOf(staticTarget)); |
| 1319 pop(); | 1329 pop(); |
| 1320 } else { | 1330 } else { |
| 1321 add(new HStaticStore( | 1331 add(new HStaticStore( |
| 1322 astAdapter.getMember(staticTarget), | 1332 astAdapter.getMember(staticTarget), |
| 1323 typeBuilder.potentiallyCheckOrTrustType( | 1333 typeBuilder.potentiallyCheckOrTrustType(value, |
| 1324 value, astAdapter.getDartType(staticTarget.setterType)))); | 1334 astAdapter.getDartTypeInvalidNull(staticTarget.setterType)))); |
| 1325 } | 1335 } |
| 1326 stack.add(value); | 1336 stack.add(value); |
| 1327 } | 1337 } |
| 1328 | 1338 |
| 1329 @override | 1339 @override |
| 1330 void visitPropertyGet(ir.PropertyGet propertyGet) { | 1340 void visitPropertyGet(ir.PropertyGet propertyGet) { |
| 1331 propertyGet.receiver.accept(this); | 1341 propertyGet.receiver.accept(this); |
| 1332 HInstruction receiver = pop(); | 1342 HInstruction receiver = pop(); |
| 1333 | 1343 |
| 1334 _pushDynamicInvocation(propertyGet, astAdapter.typeOfGet(propertyGet), | 1344 _pushDynamicInvocation(propertyGet, astAdapter.typeOfGet(propertyGet), |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1393 | 1403 |
| 1394 // Give the value a name if it doesn't have one already. | 1404 // Give the value a name if it doesn't have one already. |
| 1395 if (value.sourceElement == null) { | 1405 if (value.sourceElement == null) { |
| 1396 value.sourceElement = local; | 1406 value.sourceElement = local; |
| 1397 } | 1407 } |
| 1398 | 1408 |
| 1399 stack.add(value); | 1409 stack.add(value); |
| 1400 localsHandler.updateLocal( | 1410 localsHandler.updateLocal( |
| 1401 local, | 1411 local, |
| 1402 typeBuilder.potentiallyCheckOrTrustType( | 1412 typeBuilder.potentiallyCheckOrTrustType( |
| 1403 value, astAdapter.getDartType(variable.type))); | 1413 value, astAdapter.getDartTypeInvalidNull(variable.type))); |
| 1404 } | 1414 } |
| 1405 | 1415 |
| 1406 @override | 1416 @override |
| 1407 void visitLet(ir.Let let) { | 1417 void visitLet(ir.Let let) { |
| 1408 ir.VariableDeclaration variable = let.variable; | 1418 ir.VariableDeclaration variable = let.variable; |
| 1409 variable.initializer.accept(this); | 1419 variable.initializer.accept(this); |
| 1410 HInstruction initializedValue = pop(); | 1420 HInstruction initializedValue = pop(); |
| 1411 // TODO(sra): Apply inferred type information. | 1421 // TODO(sra): Apply inferred type information. |
| 1412 letBindings[variable] = initializedValue; | 1422 letBindings[variable] = initializedValue; |
| 1413 let.body.accept(this); | 1423 let.body.accept(this); |
| (...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2127 _visitArgumentsForStaticTarget(target.function, invocation.arguments); | 2137 _visitArgumentsForStaticTarget(target.function, invocation.arguments); |
| 2128 TypeMask typeMask = new TypeMask.nonNullExact( | 2138 TypeMask typeMask = new TypeMask.nonNullExact( |
| 2129 astAdapter.getClass(target.enclosingClass), closedWorld); | 2139 astAdapter.getClass(target.enclosingClass), closedWorld); |
| 2130 _pushStaticInvocation(target, arguments, typeMask); | 2140 _pushStaticInvocation(target, arguments, typeMask); |
| 2131 } | 2141 } |
| 2132 | 2142 |
| 2133 @override | 2143 @override |
| 2134 void visitIsExpression(ir.IsExpression isExpression) { | 2144 void visitIsExpression(ir.IsExpression isExpression) { |
| 2135 isExpression.operand.accept(this); | 2145 isExpression.operand.accept(this); |
| 2136 HInstruction expression = pop(); | 2146 HInstruction expression = pop(); |
| 2137 push(buildIsNode(isExpression, isExpression.type, expression)); | 2147 pushIsTest(isExpression, isExpression.type, expression); |
| 2138 } | 2148 } |
| 2139 | 2149 |
| 2140 HInstruction buildIsNode( | 2150 void pushIsTest(ir.Node node, ir.DartType type, HInstruction expression) { |
| 2141 ir.Node node, ir.DartType type, HInstruction expression) { | |
| 2142 // Note: The call to "unalias" this type like in the original SSA builder is | 2151 // Note: The call to "unalias" this type like in the original SSA builder is |
| 2143 // unnecessary in kernel because Kernel has no notion of typedef. | 2152 // unnecessary in kernel because Kernel has no notion of typedef. |
| 2144 // TODO(efortuna): Add test for this. | 2153 // TODO(efortuna): Add test for this. |
| 2154 | |
| 2155 if (type is ir.InvalidType) { | |
| 2156 // TODO(sra): Make InvalidType carry a message. | |
| 2157 generateTypeError(node, 'invalid type'); | |
| 2158 pop(); | |
| 2159 stack.add(graph.addConstantBool(true, closedWorld)); | |
| 2160 return; | |
| 2161 } | |
| 2162 | |
| 2145 ResolutionDartType typeValue = | 2163 ResolutionDartType typeValue = |
| 2146 localsHandler.substInContext(astAdapter.getDartType(type)); | 2164 localsHandler.substInContext(astAdapter.getDartType(type)); |
| 2147 if (type is ir.InvalidType) { | |
| 2148 generateTypeError(node, (typeValue.element as ErroneousElement).message); | |
| 2149 return new HIs.compound( | |
| 2150 typeValue, expression, pop(), commonMasks.boolType); | |
| 2151 } | |
| 2152 | |
| 2153 if (type is ir.FunctionType) { | 2165 if (type is ir.FunctionType) { |
| 2154 List arguments = [buildFunctionType(typeValue), expression]; | 2166 List arguments = [buildFunctionType(typeValue), expression]; |
| 2155 _pushDynamicInvocation(node, null, arguments, | 2167 _pushDynamicInvocation(node, null, arguments, |
| 2156 selector: new Selector.call( | 2168 selector: new Selector.call( |
| 2157 new PrivateName('_isTest', backend.helpers.jsHelperLibrary), | 2169 new PrivateName('_isTest', backend.helpers.jsHelperLibrary), |
| 2158 CallStructure.ONE_ARG)); | 2170 CallStructure.ONE_ARG)); |
| 2159 return new HIs.compound( | 2171 push( |
| 2160 typeValue, expression, pop(), commonMasks.boolType); | 2172 new HIs.compound(typeValue, expression, pop(), commonMasks.boolType)); |
| 2173 return; | |
| 2161 } | 2174 } |
| 2162 | 2175 |
| 2163 if (type is ir.TypeParameterType) { | 2176 if (type is ir.TypeParameterType) { |
| 2164 HInstruction runtimeType = | 2177 HInstruction runtimeType = |
| 2165 typeBuilder.addTypeVariableReference(typeValue, sourceElement); | 2178 typeBuilder.addTypeVariableReference(typeValue, sourceElement); |
| 2166 _pushStaticInvocation(astAdapter.checkSubtypeOfRuntimeType, | 2179 _pushStaticInvocation(astAdapter.checkSubtypeOfRuntimeType, |
| 2167 <HInstruction>[expression, runtimeType], commonMasks.boolType); | 2180 <HInstruction>[expression, runtimeType], commonMasks.boolType); |
| 2168 return new HIs.variable( | 2181 push( |
| 2169 typeValue, expression, pop(), commonMasks.boolType); | 2182 new HIs.variable(typeValue, expression, pop(), commonMasks.boolType)); |
| 2183 return; | |
| 2170 } | 2184 } |
| 2171 | 2185 |
| 2172 if (_isInterfaceWithNoDynamicTypes(type)) { | 2186 if (_isInterfaceWithNoDynamicTypes(type)) { |
| 2173 HInstruction representations = typeBuilder | 2187 HInstruction representations = typeBuilder |
| 2174 .buildTypeArgumentRepresentations(typeValue, sourceElement); | 2188 .buildTypeArgumentRepresentations(typeValue, sourceElement); |
| 2175 add(representations); | 2189 add(representations); |
| 2176 ClassElement element = typeValue.element; | 2190 ClassElement element = typeValue.element; |
| 2177 js.Name operator = backend.namer.operatorIs(element); | 2191 js.Name operator = backend.namer.operatorIs(element); |
| 2178 HInstruction isFieldName = | 2192 HInstruction isFieldName = |
| 2179 graph.addConstantStringFromName(operator, closedWorld); | 2193 graph.addConstantStringFromName(operator, closedWorld); |
| 2180 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element) | 2194 HInstruction asFieldName = closedWorld.hasAnyStrictSubtype(element) |
| 2181 ? graph.addConstantStringFromName( | 2195 ? graph.addConstantStringFromName( |
| 2182 backend.namer.substitutionName(element), closedWorld) | 2196 backend.namer.substitutionName(element), closedWorld) |
| 2183 : graph.addConstantNull(closedWorld); | 2197 : graph.addConstantNull(closedWorld); |
| 2184 List<HInstruction> inputs = <HInstruction>[ | 2198 List<HInstruction> inputs = <HInstruction>[ |
| 2185 expression, | 2199 expression, |
| 2186 isFieldName, | 2200 isFieldName, |
| 2187 representations, | 2201 representations, |
| 2188 asFieldName | 2202 asFieldName |
| 2189 ]; | 2203 ]; |
| 2190 _pushStaticInvocation( | 2204 _pushStaticInvocation( |
| 2191 astAdapter.checkSubtype, inputs, commonMasks.boolType); | 2205 astAdapter.checkSubtype, inputs, commonMasks.boolType); |
| 2192 return new HIs.compound( | 2206 push( |
| 2193 typeValue, expression, pop(), commonMasks.boolType); | 2207 new HIs.compound(typeValue, expression, pop(), commonMasks.boolType)); |
| 2208 return; | |
| 2194 } | 2209 } |
| 2195 | 2210 |
| 2196 if (backend.hasDirectCheckFor(typeValue)) { | 2211 if (backend.hasDirectCheckFor(typeValue)) { |
| 2197 return new HIs.direct(typeValue, expression, commonMasks.boolType); | 2212 push(new HIs.direct(typeValue, expression, commonMasks.boolType)); |
| 2213 return; | |
| 2198 } | 2214 } |
| 2199 // The interceptor is not always needed. It is removed by optimization | 2215 // The interceptor is not always needed. It is removed by optimization |
| 2200 // when the receiver type or tested type permit. | 2216 // when the receiver type or tested type permit. |
| 2201 return new HIs.raw(typeValue, expression, _interceptorFor(expression), | 2217 push(new HIs.raw(typeValue, expression, _interceptorFor(expression), |
| 2202 commonMasks.boolType); | 2218 commonMasks.boolType)); |
| 2219 return; | |
| 2203 } | 2220 } |
| 2204 | 2221 |
| 2205 bool _isInterfaceWithNoDynamicTypes(ir.DartType type) { | 2222 bool _isInterfaceWithNoDynamicTypes(ir.DartType type) { |
| 2206 bool isMethodTypeVariableType(ir.DartType typeArgType) { | 2223 bool isMethodTypeVariableType(ir.DartType typeArgType) { |
| 2207 return (typeArgType is ir.TypeParameterType && | 2224 return (typeArgType is ir.TypeParameterType && |
| 2208 typeArgType.parameter.parent is ir.FunctionNode); | 2225 typeArgType.parameter.parent is ir.FunctionNode); |
| 2209 } | 2226 } |
| 2210 | 2227 |
| 2211 return type is ir.InterfaceType && | 2228 return type is ir.InterfaceType && |
| 2212 (type as ir.InterfaceType).typeArguments.any( | 2229 (type as ir.InterfaceType).typeArguments.any( |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2439 kernelBuilder._pushStaticInvocation( | 2456 kernelBuilder._pushStaticInvocation( |
| 2440 kernelBuilder.astAdapter.exceptionUnwrapper, | 2457 kernelBuilder.astAdapter.exceptionUnwrapper, |
| 2441 [exception], | 2458 [exception], |
| 2442 kernelBuilder.astAdapter.exceptionUnwrapperType); | 2459 kernelBuilder.astAdapter.exceptionUnwrapperType); |
| 2443 HInvokeStatic unwrappedException = kernelBuilder.pop(); | 2460 HInvokeStatic unwrappedException = kernelBuilder.pop(); |
| 2444 tryInstruction.exception = exception; | 2461 tryInstruction.exception = exception; |
| 2445 int catchesIndex = 0; | 2462 int catchesIndex = 0; |
| 2446 | 2463 |
| 2447 void pushCondition(ir.Catch catchBlock) { | 2464 void pushCondition(ir.Catch catchBlock) { |
| 2448 if (catchBlock.guard is! ir.DynamicType) { | 2465 if (catchBlock.guard is! ir.DynamicType) { |
| 2449 HInstruction condition = kernelBuilder.buildIsNode( | 2466 kernelBuilder.pushIsTest( |
| 2450 catchBlock.exception, catchBlock.guard, unwrappedException); | 2467 catchBlock.exception, catchBlock.guard, unwrappedException); |
| 2451 kernelBuilder.push(condition); | |
| 2452 } else { | 2468 } else { |
| 2453 kernelBuilder.stack.add(kernelBuilder.graph | 2469 kernelBuilder.stack.add(kernelBuilder.graph |
|
Siggi Cherem (dart-lang)
2017/01/13 16:38:22
actually - should we handle `guard is DynamicType`
sra1
2017/01/13 18:53:11
Done.
| |
| 2454 .addConstantBool(true, kernelBuilder.closedWorld)); | 2470 .addConstantBool(true, kernelBuilder.closedWorld)); |
| 2455 } | 2471 } |
| 2456 } | 2472 } |
| 2457 | 2473 |
| 2458 void visitThen() { | 2474 void visitThen() { |
| 2459 ir.Catch catchBlock = tryCatch.catches[catchesIndex]; | 2475 ir.Catch catchBlock = tryCatch.catches[catchesIndex]; |
| 2460 catchesIndex++; | 2476 catchesIndex++; |
| 2461 if (catchBlock.exception != null) { | 2477 if (catchBlock.exception != null) { |
| 2462 LocalVariableElement exceptionVariable = | 2478 LocalVariableElement exceptionVariable = |
| 2463 kernelBuilder.astAdapter.getElement(catchBlock.exception); | 2479 kernelBuilder.astAdapter.getElement(catchBlock.exception); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2523 kernelBuilder.open(exitBlock); | 2539 kernelBuilder.open(exitBlock); |
| 2524 enterBlock.setBlockFlow( | 2540 enterBlock.setBlockFlow( |
| 2525 new HTryBlockInformation( | 2541 new HTryBlockInformation( |
| 2526 kernelBuilder.wrapStatementGraph(bodyGraph), | 2542 kernelBuilder.wrapStatementGraph(bodyGraph), |
| 2527 exception, | 2543 exception, |
| 2528 kernelBuilder.wrapStatementGraph(catchGraph), | 2544 kernelBuilder.wrapStatementGraph(catchGraph), |
| 2529 kernelBuilder.wrapStatementGraph(finallyGraph)), | 2545 kernelBuilder.wrapStatementGraph(finallyGraph)), |
| 2530 exitBlock); | 2546 exitBlock); |
| 2531 } | 2547 } |
| 2532 } | 2548 } |
| OLD | NEW |