Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(291)

Side by Side Diff: pkg/compiler/lib/src/ssa/builder_kernel.dart

Issue 2630633002: dart2js-kernel: special-case InvalidType in 'is' and 'as' (Closed)
Patch Set: format Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('j') | pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698