| 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 import 'dart:collection'; | 5 import 'dart:collection'; |
| 6 | 6 |
| 7 import 'package:js_runtime/shared/embedded_names.dart'; | 7 import 'package:js_runtime/shared/embedded_names.dart'; |
| 8 | 8 |
| 9 import '../closure.dart'; | 9 import '../closure.dart'; |
| 10 import '../common.dart'; | 10 import '../common.dart'; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter; | 29 import '../js_emitter/js_emitter.dart' show CodeEmitterTask, NativeEmitter; |
| 30 import '../native/native.dart' as native; | 30 import '../native/native.dart' as native; |
| 31 import '../resolution/operators.dart'; | 31 import '../resolution/operators.dart'; |
| 32 import '../resolution/semantic_visitor.dart'; | 32 import '../resolution/semantic_visitor.dart'; |
| 33 import '../resolution/tree_elements.dart' show TreeElements; | 33 import '../resolution/tree_elements.dart' show TreeElements; |
| 34 import '../tree/tree.dart' as ast; | 34 import '../tree/tree.dart' as ast; |
| 35 import '../types/types.dart'; | 35 import '../types/types.dart'; |
| 36 import '../universe/call_structure.dart' show CallStructure; | 36 import '../universe/call_structure.dart' show CallStructure; |
| 37 import '../universe/selector.dart' show Selector; | 37 import '../universe/selector.dart' show Selector; |
| 38 import '../universe/side_effects.dart' show SideEffects; | 38 import '../universe/side_effects.dart' show SideEffects; |
| 39 import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse; | 39 import '../universe/use.dart' show DynamicUse, StaticUse; |
| 40 import '../util/util.dart'; | 40 import '../util/util.dart'; |
| 41 import '../world.dart' show ClosedWorld; | 41 import '../world.dart' show ClosedWorld; |
| 42 | 42 |
| 43 import 'graph_builder.dart'; | 43 import 'graph_builder.dart'; |
| 44 import 'jump_handler.dart'; | 44 import 'jump_handler.dart'; |
| 45 import 'locals_handler.dart'; | 45 import 'locals_handler.dart'; |
| 46 import 'loop_handler.dart'; | 46 import 'loop_handler.dart'; |
| 47 import 'nodes.dart'; | 47 import 'nodes.dart'; |
| 48 import 'optimize.dart'; | 48 import 'optimize.dart'; |
| 49 import 'ssa_branch_builder.dart'; | 49 import 'ssa_branch_builder.dart'; |
| 50 import 'type_verifier.dart'; |
| 50 import 'types.dart'; | 51 import 'types.dart'; |
| 51 | 52 |
| 52 class SsaBuilderTask extends CompilerTask { | 53 class SsaBuilderTask extends CompilerTask { |
| 53 final CodeEmitterTask emitter; | 54 final CodeEmitterTask emitter; |
| 54 final JavaScriptBackend backend; | 55 final JavaScriptBackend backend; |
| 55 final SourceInformationStrategy sourceInformationFactory; | 56 final SourceInformationStrategy sourceInformationFactory; |
| 56 final Compiler compiler; | 57 final Compiler compiler; |
| 57 | 58 |
| 58 String get name => 'SSA builder'; | 59 String get name => 'SSA builder'; |
| 59 | 60 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 /// Returns `true` if the current element is an `async` function. | 182 /// Returns `true` if the current element is an `async` function. |
| 182 bool get isBuildingAsyncFunction { | 183 bool get isBuildingAsyncFunction { |
| 183 Element element = sourceElement; | 184 Element element = sourceElement; |
| 184 return (element is FunctionElement && | 185 return (element is FunctionElement && |
| 185 element.asyncMarker == AsyncMarker.ASYNC); | 186 element.asyncMarker == AsyncMarker.ASYNC); |
| 186 } | 187 } |
| 187 | 188 |
| 188 /// Handles the building of loops. | 189 /// Handles the building of loops. |
| 189 LoopHandler<ast.Node> loopHandler; | 190 LoopHandler<ast.Node> loopHandler; |
| 190 | 191 |
| 192 /// Handles type check building. |
| 193 TypeVerifier typeVerifier; |
| 194 |
| 191 // TODO(sigmund): make most args optional | 195 // TODO(sigmund): make most args optional |
| 192 SsaBuilder( | 196 SsaBuilder( |
| 193 this.target, | 197 this.target, |
| 194 this.resolvedAst, | 198 this.resolvedAst, |
| 195 this.registry, | 199 this.registry, |
| 196 JavaScriptBackend backend, | 200 JavaScriptBackend backend, |
| 197 this.nativeEmitter, | 201 this.nativeEmitter, |
| 198 SourceInformationStrategy sourceInformationFactory) | 202 SourceInformationStrategy sourceInformationFactory) |
| 199 : this.infoReporter = backend.compiler.dumpInfoTask, | 203 : this.infoReporter = backend.compiler.dumpInfoTask, |
| 200 this.backend = backend, | 204 this.backend = backend, |
| 201 this.constantSystem = backend.constantSystem, | 205 this.constantSystem = backend.constantSystem, |
| 202 this.rti = backend.rti, | 206 this.rti = backend.rti, |
| 203 this.inferenceResults = backend.compiler.globalInference.results { | 207 this.inferenceResults = backend.compiler.globalInference.results { |
| 204 assert(target.isImplementation); | 208 assert(target.isImplementation); |
| 205 compiler = backend.compiler; | 209 compiler = backend.compiler; |
| 206 elementInferenceResults = _resultOf(target); | 210 elementInferenceResults = _resultOf(target); |
| 207 assert(elementInferenceResults != null); | 211 assert(elementInferenceResults != null); |
| 208 graph.element = target; | 212 graph.element = target; |
| 209 sourceElementStack.add(target); | 213 sourceElementStack.add(target); |
| 210 sourceInformationBuilder = | 214 sourceInformationBuilder = |
| 211 sourceInformationFactory.createBuilderForContext(resolvedAst); | 215 sourceInformationFactory.createBuilderForContext(resolvedAst); |
| 212 graph.sourceInformation = | 216 graph.sourceInformation = |
| 213 sourceInformationBuilder.buildVariableDeclaration(); | 217 sourceInformationBuilder.buildVariableDeclaration(); |
| 214 localsHandler = new LocalsHandler(this, target, null, compiler); | 218 localsHandler = new LocalsHandler(this, target, null, compiler); |
| 215 loopHandler = new SsaLoopHandler(this); | 219 loopHandler = new SsaLoopHandler(this); |
| 220 typeVerifier = new TypeVerifier(this); |
| 216 } | 221 } |
| 217 | 222 |
| 218 BackendHelpers get helpers => backend.helpers; | 223 BackendHelpers get helpers => backend.helpers; |
| 219 | 224 |
| 220 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; | 225 RuntimeTypesEncoder get rtiEncoder => backend.rtiEncoder; |
| 221 | 226 |
| 222 DiagnosticReporter get reporter => compiler.reporter; | 227 DiagnosticReporter get reporter => compiler.reporter; |
| 223 | 228 |
| 224 CoreClasses get coreClasses => compiler.coreClasses; | 229 CoreClasses get coreClasses => compiler.coreClasses; |
| 225 | 230 |
| 231 Element get targetElement => target; |
| 232 |
| 226 /// Reference to resolved elements in [target]'s AST. | 233 /// Reference to resolved elements in [target]'s AST. |
| 227 TreeElements get elements => resolvedAst.elements; | 234 TreeElements get elements => resolvedAst.elements; |
| 228 | 235 |
| 229 @override | 236 @override |
| 230 SemanticSendVisitor get sendVisitor => this; | 237 SemanticSendVisitor get sendVisitor => this; |
| 231 | 238 |
| 232 @override | 239 @override |
| 233 void visitNode(ast.Node node) { | 240 void visitNode(ast.Node node) { |
| 234 internalError(node, "Unhandled node: $node"); | 241 internalError(node, "Unhandled node: $node"); |
| 235 } | 242 } |
| 236 | 243 |
| 237 @override | 244 @override |
| 238 void apply(ast.Node node, [_]) { | 245 void apply(ast.Node node, [_]) { |
| 239 node.accept(this); | 246 node.accept(this); |
| 240 } | 247 } |
| 241 | 248 |
| 242 /// Returns the current source element. | 249 /// Returns the current source element. |
| 243 /// | 250 /// |
| 244 /// The returned element is a declaration element. | 251 /// The returned element is a declaration element. |
| 245 // TODO(johnniwinther): Check that all usages of sourceElement agree on | 252 // TODO(johnniwinther): Check that all usages of sourceElement agree on |
| 246 // implementation/declaration distinction. | 253 // implementation/declaration distinction. |
| 254 @override |
| 247 Element get sourceElement => sourceElementStack.last; | 255 Element get sourceElement => sourceElementStack.last; |
| 248 | 256 |
| 249 /// Helper to retrieve global inference results for [element] with special | 257 /// Helper to retrieve global inference results for [element] with special |
| 250 /// care for `ConstructorBodyElement`s which don't exist at the time the | 258 /// care for `ConstructorBodyElement`s which don't exist at the time the |
| 251 /// global analysis run. | 259 /// global analysis run. |
| 252 /// | 260 /// |
| 253 /// Note: this helper is used selectively. When we know that we are in a | 261 /// Note: this helper is used selectively. When we know that we are in a |
| 254 /// context were we don't expect to see a constructor body element, we | 262 /// context were we don't expect to see a constructor body element, we |
| 255 /// directly fetch the data from the global inference results. | 263 /// directly fetch the data from the global inference results. |
| 256 GlobalTypeInferenceElementResult _resultOf(AstElement element) => | 264 GlobalTypeInferenceElementResult _resultOf(AstElement element) => |
| 257 inferenceResults.resultOf( | 265 inferenceResults.resultOf( |
| 258 element is ConstructorBodyElementX ? element.constructor : element); | 266 element is ConstructorBodyElementX ? element.constructor : element); |
| 259 | 267 |
| 260 bool get _checkOrTrustTypes => | |
| 261 compiler.options.enableTypeAssertions || | |
| 262 compiler.options.trustTypeAnnotations; | |
| 263 | |
| 264 /// Build the graph for [target]. | 268 /// Build the graph for [target]. |
| 265 HGraph build() { | 269 HGraph build() { |
| 266 assert(invariant(target, target.isImplementation)); | 270 assert(invariant(target, target.isImplementation)); |
| 267 HInstruction.idCounter = 0; | 271 HInstruction.idCounter = 0; |
| 268 // TODO(sigmund): remove `result` and return graph directly, need to ensure | 272 // TODO(sigmund): remove `result` and return graph directly, need to ensure |
| 269 // that it can never be null (see result in buildFactory for instance). | 273 // that it can never be null (see result in buildFactory for instance). |
| 270 var result; | 274 var result; |
| 271 if (target.isGenerativeConstructor) { | 275 if (target.isGenerativeConstructor) { |
| 272 result = buildFactory(resolvedAst); | 276 result = buildFactory(resolvedAst); |
| 273 } else if (target.isGenerativeConstructorBody || | 277 } else if (target.isGenerativeConstructorBody || |
| (...skipping 13 matching lines...) Expand all Loading... |
| 287 reporter.internalError(target, 'Unexpected element kind $target.'); | 291 reporter.internalError(target, 'Unexpected element kind $target.'); |
| 288 } | 292 } |
| 289 assert(result.isValid()); | 293 assert(result.isValid()); |
| 290 return result; | 294 return result; |
| 291 } | 295 } |
| 292 | 296 |
| 293 void addWithPosition(HInstruction instruction, ast.Node node) { | 297 void addWithPosition(HInstruction instruction, ast.Node node) { |
| 294 add(attachPosition(instruction, node)); | 298 add(attachPosition(instruction, node)); |
| 295 } | 299 } |
| 296 | 300 |
| 301 HTypeConversion buildFunctionTypeConversion(HInstruction original, |
| 302 DartType type, int kind) { |
| 303 String name = |
| 304 kind == HTypeConversion.CAST_TYPE_CHECK ? '_asCheck' : '_assertCheck'; |
| 305 |
| 306 List<HInstruction> arguments = <HInstruction>[ |
| 307 buildFunctionType(type), |
| 308 original |
| 309 ]; |
| 310 pushInvokeDynamic( |
| 311 null, |
| 312 new Selector.call( |
| 313 new Name(name, helpers.jsHelperLibrary), CallStructure.ONE_ARG), |
| 314 null, |
| 315 arguments); |
| 316 |
| 317 return new HTypeConversion(type, kind, original.instructionType, pop()); |
| 318 } |
| 319 |
| 297 /** | 320 /** |
| 298 * Returns a complete argument list for a call of [function]. | 321 * Returns a complete argument list for a call of [function]. |
| 299 */ | 322 */ |
| 300 List<HInstruction> completeSendArgumentsList( | 323 List<HInstruction> completeSendArgumentsList( |
| 301 FunctionElement function, | 324 FunctionElement function, |
| 302 Selector selector, | 325 Selector selector, |
| 303 List<HInstruction> providedArguments, | 326 List<HInstruction> providedArguments, |
| 304 ast.Node currentNode) { | 327 ast.Node currentNode) { |
| 305 assert(invariant(function, function.isImplementation)); | 328 assert(invariant(function, function.isImplementation)); |
| 306 assert(providedArguments != null); | 329 assert(providedArguments != null); |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 ResolvedAst resolvedAst = field.resolvedAst; | 767 ResolvedAst resolvedAst = field.resolvedAst; |
| 745 openFunction(field, resolvedAst.node); | 768 openFunction(field, resolvedAst.node); |
| 746 HInstruction thisInstruction = localsHandler.readThis(); | 769 HInstruction thisInstruction = localsHandler.readThis(); |
| 747 // Use dynamic type because the type computed by the inferrer is | 770 // Use dynamic type because the type computed by the inferrer is |
| 748 // narrowed to the type annotation. | 771 // narrowed to the type annotation. |
| 749 HInstruction parameter = new HParameterValue(field, backend.dynamicType); | 772 HInstruction parameter = new HParameterValue(field, backend.dynamicType); |
| 750 // Add the parameter as the last instruction of the entry block. | 773 // Add the parameter as the last instruction of the entry block. |
| 751 // If the method is intercepted, we want the actual receiver | 774 // If the method is intercepted, we want the actual receiver |
| 752 // to be the first parameter. | 775 // to be the first parameter. |
| 753 graph.entry.addBefore(graph.entry.last, parameter); | 776 graph.entry.addBefore(graph.entry.last, parameter); |
| 754 HInstruction value = potentiallyCheckOrTrustType(parameter, field.type); | 777 HInstruction value = typeVerifier.potentiallyCheckOrTrustType( |
| 778 parameter, field.type); |
| 755 add(new HFieldSet(field, thisInstruction, value)); | 779 add(new HFieldSet(field, thisInstruction, value)); |
| 756 return closeFunction(); | 780 return closeFunction(); |
| 757 } | 781 } |
| 758 | 782 |
| 759 HGraph buildLazyInitializer(VariableElement variable) { | 783 HGraph buildLazyInitializer(VariableElement variable) { |
| 760 assert(invariant(variable, resolvedAst.element == variable, | 784 assert(invariant(variable, resolvedAst.element == variable, |
| 761 message: "Unexpected variable $variable for $resolvedAst.")); | 785 message: "Unexpected variable $variable for $resolvedAst.")); |
| 762 inLazyInitializerExpression = true; | 786 inLazyInitializerExpression = true; |
| 763 ast.VariableDefinitions node = resolvedAst.node; | 787 ast.VariableDefinitions node = resolvedAst.node; |
| 764 ast.Node initializer = resolvedAst.body; | 788 ast.Node initializer = resolvedAst.body; |
| 765 assert(invariant(variable, initializer != null, | 789 assert(invariant(variable, initializer != null, |
| 766 message: "Non-constant variable $variable has no initializer.")); | 790 message: "Non-constant variable $variable has no initializer.")); |
| 767 openFunction(variable, node); | 791 openFunction(variable, node); |
| 768 visit(initializer); | 792 visit(initializer); |
| 769 HInstruction value = pop(); | 793 HInstruction value = pop(); |
| 770 value = potentiallyCheckOrTrustType(value, variable.type); | 794 value = typeVerifier.potentiallyCheckOrTrustType(value, variable.type); |
| 771 // In the case of multiple declarations (and some definitions) on the same | 795 // In the case of multiple declarations (and some definitions) on the same |
| 772 // line, the source pointer needs to point to the right initialized | 796 // line, the source pointer needs to point to the right initialized |
| 773 // variable. So find the specific initialized variable we are referring to. | 797 // variable. So find the specific initialized variable we are referring to. |
| 774 ast.Node sourceInfoNode = initializer; | 798 ast.Node sourceInfoNode = initializer; |
| 775 for (var definition in node.definitions) { | 799 for (var definition in node.definitions) { |
| 776 if (definition is ast.SendSet && | 800 if (definition is ast.SendSet && |
| 777 definition.selector.asIdentifier().source == variable.name) { | 801 definition.selector.asIdentifier().source == variable.name) { |
| 778 sourceInfoNode = definition.assignmentOperator; | 802 sourceInfoNode = definition.assignmentOperator; |
| 779 break; | 803 break; |
| 780 } | 804 } |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 892 elementInferenceResults = state.oldElementInferenceResults; | 916 elementInferenceResults = state.oldElementInferenceResults; |
| 893 returnType = state.oldReturnType; | 917 returnType = state.oldReturnType; |
| 894 assert(stack.isEmpty); | 918 assert(stack.isEmpty); |
| 895 stack = state.oldStack; | 919 stack = state.oldStack; |
| 896 } | 920 } |
| 897 | 921 |
| 898 /** | 922 /** |
| 899 * Run this builder on the body of the [function] to be inlined. | 923 * Run this builder on the body of the [function] to be inlined. |
| 900 */ | 924 */ |
| 901 void visitInlinedFunction(ResolvedAst resolvedAst) { | 925 void visitInlinedFunction(ResolvedAst resolvedAst) { |
| 902 potentiallyCheckInlinedParameterTypes(resolvedAst.element.implementation); | 926 typeVerifier.potentiallyCheckInlinedParameterTypes( |
| 927 resolvedAst.element.implementation); |
| 903 | 928 |
| 904 if (resolvedAst.element.isGenerativeConstructor) { | 929 if (resolvedAst.element.isGenerativeConstructor) { |
| 905 buildFactory(resolvedAst); | 930 buildFactory(resolvedAst); |
| 906 } else { | 931 } else { |
| 907 ast.FunctionExpression functionNode = resolvedAst.node; | 932 ast.FunctionExpression functionNode = resolvedAst.node; |
| 908 functionNode.body.accept(this); | 933 functionNode.body.accept(this); |
| 909 } | 934 } |
| 910 } | 935 } |
| 911 | 936 |
| 912 addInlinedInstantiation(DartType type) { | 937 addInlinedInstantiation(DartType type) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 925 /* When inlining the iterator methods generated for a [:for-in:] loop, the | 950 /* When inlining the iterator methods generated for a [:for-in:] loop, the |
| 926 * [currentNode] is the [ForIn] tree. The compiler-generated iterator | 951 * [currentNode] is the [ForIn] tree. The compiler-generated iterator |
| 927 * invocations are known to have fully specified argument lists, no default | 952 * invocations are known to have fully specified argument lists, no default |
| 928 * arguments are used. See invocations of [pushInvokeDynamic] in | 953 * arguments are used. See invocations of [pushInvokeDynamic] in |
| 929 * [visitForIn]. | 954 * [visitForIn]. |
| 930 */ | 955 */ |
| 931 return currentNode.asForIn() != null; | 956 return currentNode.asForIn() != null; |
| 932 } | 957 } |
| 933 | 958 |
| 934 /** | 959 /** |
| 935 * In checked mode, generate type tests for the parameters of the inlined | |
| 936 * function. | |
| 937 */ | |
| 938 void potentiallyCheckInlinedParameterTypes(FunctionElement function) { | |
| 939 if (!_checkOrTrustTypes) return; | |
| 940 | |
| 941 FunctionSignature signature = function.functionSignature; | |
| 942 signature.orderedForEachParameter((ParameterElement parameter) { | |
| 943 HInstruction argument = localsHandler.readLocal(parameter); | |
| 944 potentiallyCheckOrTrustType(argument, parameter.type); | |
| 945 }); | |
| 946 } | |
| 947 | |
| 948 /** | |
| 949 * Documentation wanted -- johnniwinther | 960 * Documentation wanted -- johnniwinther |
| 950 * | 961 * |
| 951 * Invariant: [constructors] must contain only implementation elements. | 962 * Invariant: [constructors] must contain only implementation elements. |
| 952 */ | 963 */ |
| 953 void inlineSuperOrRedirect( | 964 void inlineSuperOrRedirect( |
| 954 ResolvedAst constructorResolvedAst, | 965 ResolvedAst constructorResolvedAst, |
| 955 List<HInstruction> compiledArguments, | 966 List<HInstruction> compiledArguments, |
| 956 List<ResolvedAst> constructorResolvedAsts, | 967 List<ResolvedAst> constructorResolvedAsts, |
| 957 Map<Element, HInstruction> fieldValues, | 968 Map<Element, HInstruction> fieldValues, |
| 958 FunctionElement caller) { | 969 FunctionElement caller) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 973 List<DartType> arguments = type.typeArguments; | 984 List<DartType> arguments = type.typeArguments; |
| 974 List<DartType> typeVariables = enclosingClass.typeVariables; | 985 List<DartType> typeVariables = enclosingClass.typeVariables; |
| 975 if (!type.isRaw) { | 986 if (!type.isRaw) { |
| 976 assert(arguments.length == typeVariables.length); | 987 assert(arguments.length == typeVariables.length); |
| 977 Iterator<DartType> variables = typeVariables.iterator; | 988 Iterator<DartType> variables = typeVariables.iterator; |
| 978 type.typeArguments.forEach((DartType argument) { | 989 type.typeArguments.forEach((DartType argument) { |
| 979 variables.moveNext(); | 990 variables.moveNext(); |
| 980 TypeVariableType typeVariable = variables.current; | 991 TypeVariableType typeVariable = variables.current; |
| 981 localsHandler.updateLocal( | 992 localsHandler.updateLocal( |
| 982 localsHandler.getTypeVariableAsLocal(typeVariable), | 993 localsHandler.getTypeVariableAsLocal(typeVariable), |
| 983 analyzeTypeArgument(argument)); | 994 typeVerifier.analyzeTypeArgument(argument, sourceElement)); |
| 984 }); | 995 }); |
| 985 } else { | 996 } else { |
| 986 // If the supertype is a raw type, we need to set to null the | 997 // If the supertype is a raw type, we need to set to null the |
| 987 // type variables. | 998 // type variables. |
| 988 for (TypeVariableType variable in typeVariables) { | 999 for (TypeVariableType variable in typeVariables) { |
| 989 localsHandler.updateLocal( | 1000 localsHandler.updateLocal( |
| 990 localsHandler.getTypeVariableAsLocal(variable), | 1001 localsHandler.getTypeVariableAsLocal(variable), |
| 991 graph.addConstantNull(compiler)); | 1002 graph.addConstantNull(compiler)); |
| 992 } | 1003 } |
| 993 } | 1004 } |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1275 (ClassElement enclosingClass, FieldElement member) { | 1286 (ClassElement enclosingClass, FieldElement member) { |
| 1276 HInstruction value = fieldValues[member]; | 1287 HInstruction value = fieldValues[member]; |
| 1277 if (value == null) { | 1288 if (value == null) { |
| 1278 // Uninitialized native fields are pre-initialized by the native | 1289 // Uninitialized native fields are pre-initialized by the native |
| 1279 // implementation. | 1290 // implementation. |
| 1280 assert(invariant( | 1291 assert(invariant( |
| 1281 member, isNativeUpgradeFactory || compiler.compilationFailed)); | 1292 member, isNativeUpgradeFactory || compiler.compilationFailed)); |
| 1282 } else { | 1293 } else { |
| 1283 fields.add(member); | 1294 fields.add(member); |
| 1284 DartType type = localsHandler.substInContext(member.type); | 1295 DartType type = localsHandler.substInContext(member.type); |
| 1285 constructorArguments.add(potentiallyCheckOrTrustType(value, type)); | 1296 constructorArguments.add(typeVerifier.potentiallyCheckOrTrustType( |
| 1297 value, type)); |
| 1286 } | 1298 } |
| 1287 }, includeSuperAndInjectedMembers: true); | 1299 }, includeSuperAndInjectedMembers: true); |
| 1288 | 1300 |
| 1289 InterfaceType type = classElement.thisType; | 1301 InterfaceType type = classElement.thisType; |
| 1290 TypeMask ssaType = new TypeMask.nonNullExact( | 1302 TypeMask ssaType = new TypeMask.nonNullExact( |
| 1291 classElement.declaration, compiler.closedWorld); | 1303 classElement.declaration, compiler.closedWorld); |
| 1292 List<DartType> instantiatedTypes; | 1304 List<DartType> instantiatedTypes; |
| 1293 addInlinedInstantiation(type); | 1305 addInlinedInstantiation(type); |
| 1294 if (!currentInlinedInstantiations.isEmpty) { | 1306 if (!currentInlinedInstantiations.isEmpty) { |
| 1295 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); | 1307 instantiatedTypes = new List<DartType>.from(currentInlinedInstantiations); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1474 // class A { | 1486 // class A { |
| 1475 // A(String foo) = A.b; | 1487 // A(String foo) = A.b; |
| 1476 // A(int foo) { print(foo); } | 1488 // A(int foo) { print(foo); } |
| 1477 // } | 1489 // } |
| 1478 // main() { | 1490 // main() { |
| 1479 // new A(499); // valid even in checked mode. | 1491 // new A(499); // valid even in checked mode. |
| 1480 // new A("foo"); // invalid in checked mode. | 1492 // new A("foo"); // invalid in checked mode. |
| 1481 // | 1493 // |
| 1482 // Only the final target is allowed to check for the argument types. | 1494 // Only the final target is allowed to check for the argument types. |
| 1483 newParameter = | 1495 newParameter = |
| 1484 potentiallyCheckOrTrustType(newParameter, parameterElement.type); | 1496 typeVerifier.potentiallyCheckOrTrustType( |
| 1497 newParameter, parameterElement.type); |
| 1485 } | 1498 } |
| 1486 localsHandler.directLocals[parameterElement] = newParameter; | 1499 localsHandler.directLocals[parameterElement] = newParameter; |
| 1487 }); | 1500 }); |
| 1488 | 1501 |
| 1489 returnType = signature.type.returnType; | 1502 returnType = signature.type.returnType; |
| 1490 } else { | 1503 } else { |
| 1491 // Otherwise it is a lazy initializer which does not have parameters. | 1504 // Otherwise it is a lazy initializer which does not have parameters. |
| 1492 assert(element is VariableElement); | 1505 assert(element is VariableElement); |
| 1493 } | 1506 } |
| 1494 | 1507 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1512 if (JavaScriptBackend.TRACE_METHOD == 'post') { | 1525 if (JavaScriptBackend.TRACE_METHOD == 'post') { |
| 1513 if (element == backend.traceHelper) return; | 1526 if (element == backend.traceHelper) return; |
| 1514 // TODO(sigmund): create a better uuid for elements. | 1527 // TODO(sigmund): create a better uuid for elements. |
| 1515 HConstant idConstant = graph.addConstantInt(element.hashCode, compiler); | 1528 HConstant idConstant = graph.addConstantInt(element.hashCode, compiler); |
| 1516 HConstant nameConstant = addConstantString(element.name); | 1529 HConstant nameConstant = addConstantString(element.name); |
| 1517 add(new HInvokeStatic(backend.traceHelper, | 1530 add(new HInvokeStatic(backend.traceHelper, |
| 1518 <HInstruction>[idConstant, nameConstant], backend.dynamicType)); | 1531 <HInstruction>[idConstant, nameConstant], backend.dynamicType)); |
| 1519 } | 1532 } |
| 1520 } | 1533 } |
| 1521 | 1534 |
| 1522 /// Check that [type] is valid in the context of `localsHandler.contextClass`. | |
| 1523 /// This should only be called in assertions. | |
| 1524 bool assertTypeInContext(DartType type, [Spannable spannable]) { | |
| 1525 return invariant(spannable == null ? CURRENT_ELEMENT_SPANNABLE : spannable, | |
| 1526 () { | |
| 1527 ClassElement contextClass = Types.getClassContext(type); | |
| 1528 return contextClass == null || contextClass == localsHandler.contextClass; | |
| 1529 }, | |
| 1530 message: "Type '$type' is not valid context of " | |
| 1531 "${localsHandler.contextClass}."); | |
| 1532 } | |
| 1533 | |
| 1534 /// Build a [HTypeConversion] for converting [original] to type [type]. | |
| 1535 /// | |
| 1536 /// Invariant: [type] must be valid in the context. | |
| 1537 /// See [LocalsHandler.substInContext]. | |
| 1538 HInstruction buildTypeConversion( | |
| 1539 HInstruction original, DartType type, int kind) { | |
| 1540 if (type == null) return original; | |
| 1541 // GENERIC_METHODS: The following statement was added for parsing and | |
| 1542 // ignoring method type variables; must be generalized for full support of | |
| 1543 // generic methods. | |
| 1544 type = type.dynamifyMethodTypeVariableType; | |
| 1545 type = type.unaliased; | |
| 1546 assert(assertTypeInContext(type, original)); | |
| 1547 if (type.isInterfaceType && !type.treatAsRaw) { | |
| 1548 TypeMask subtype = | |
| 1549 new TypeMask.subtype(type.element, compiler.closedWorld); | |
| 1550 HInstruction representations = buildTypeArgumentRepresentations(type); | |
| 1551 add(representations); | |
| 1552 return new HTypeConversion.withTypeRepresentation( | |
| 1553 type, kind, subtype, original, representations); | |
| 1554 } else if (type.isTypeVariable) { | |
| 1555 TypeMask subtype = original.instructionType; | |
| 1556 HInstruction typeVariable = addTypeVariableReference(type); | |
| 1557 return new HTypeConversion.withTypeRepresentation( | |
| 1558 type, kind, subtype, original, typeVariable); | |
| 1559 } else if (type.isFunctionType) { | |
| 1560 String name = | |
| 1561 kind == HTypeConversion.CAST_TYPE_CHECK ? '_asCheck' : '_assertCheck'; | |
| 1562 | |
| 1563 List<HInstruction> arguments = <HInstruction>[ | |
| 1564 buildFunctionType(type), | |
| 1565 original | |
| 1566 ]; | |
| 1567 pushInvokeDynamic( | |
| 1568 null, | |
| 1569 new Selector.call( | |
| 1570 new Name(name, helpers.jsHelperLibrary), CallStructure.ONE_ARG), | |
| 1571 null, | |
| 1572 arguments); | |
| 1573 | |
| 1574 return new HTypeConversion(type, kind, original.instructionType, pop()); | |
| 1575 } else { | |
| 1576 return original.convertType(compiler, type, kind); | |
| 1577 } | |
| 1578 } | |
| 1579 | |
| 1580 HInstruction _trustType(HInstruction original, DartType type) { | |
| 1581 assert(compiler.options.trustTypeAnnotations); | |
| 1582 assert(type != null); | |
| 1583 type = localsHandler.substInContext(type); | |
| 1584 type = type.unaliased; | |
| 1585 if (type.isDynamic) return original; | |
| 1586 if (!type.isInterfaceType) return original; | |
| 1587 if (type.isObject) return original; | |
| 1588 // The type element is either a class or the void element. | |
| 1589 Element element = type.element; | |
| 1590 TypeMask mask = new TypeMask.subtype(element, compiler.closedWorld); | |
| 1591 return new HTypeKnown.pinned(mask, original); | |
| 1592 } | |
| 1593 | |
| 1594 HInstruction _checkType(HInstruction original, DartType type, int kind) { | |
| 1595 assert(compiler.options.enableTypeAssertions); | |
| 1596 assert(type != null); | |
| 1597 type = localsHandler.substInContext(type); | |
| 1598 HInstruction other = buildTypeConversion(original, type, kind); | |
| 1599 // TODO(johnniwinther): This operation on `registry` may be inconsistent. | |
| 1600 // If it is needed then it seems likely that similar invocations of | |
| 1601 // `buildTypeConversion` in `SsaBuilder.visitAs` should also be followed by | |
| 1602 // a similar operation on `registry`; otherwise, this one might not be | |
| 1603 // needed. | |
| 1604 registry?.registerTypeUse(new TypeUse.isCheck(type)); | |
| 1605 return other; | |
| 1606 } | |
| 1607 | |
| 1608 HInstruction potentiallyCheckOrTrustType(HInstruction original, DartType type, | |
| 1609 {int kind: HTypeConversion.CHECKED_MODE_CHECK}) { | |
| 1610 if (type == null) return original; | |
| 1611 HInstruction checkedOrTrusted = original; | |
| 1612 if (compiler.options.trustTypeAnnotations) { | |
| 1613 checkedOrTrusted = _trustType(original, type); | |
| 1614 } else if (compiler.options.enableTypeAssertions) { | |
| 1615 checkedOrTrusted = _checkType(original, type, kind); | |
| 1616 } | |
| 1617 if (checkedOrTrusted == original) return original; | |
| 1618 add(checkedOrTrusted); | |
| 1619 return checkedOrTrusted; | |
| 1620 } | |
| 1621 | |
| 1622 void assertIsSubtype( | 1535 void assertIsSubtype( |
| 1623 ast.Node node, DartType subtype, DartType supertype, String message) { | 1536 ast.Node node, DartType subtype, DartType supertype, String message) { |
| 1624 HInstruction subtypeInstruction = | 1537 HInstruction subtypeInstruction = |
| 1625 analyzeTypeArgument(localsHandler.substInContext(subtype)); | 1538 typeVerifier.analyzeTypeArgument(localsHandler.substInContext(subtype), |
| 1626 HInstruction supertypeInstruction = | 1539 sourceElement); |
| 1627 analyzeTypeArgument(localsHandler.substInContext(supertype)); | 1540 HInstruction supertypeInstruction = typeVerifier.analyzeTypeArgument( |
| 1541 localsHandler.substInContext(supertype), sourceElement); |
| 1628 HInstruction messageInstruction = | 1542 HInstruction messageInstruction = |
| 1629 graph.addConstantString(new ast.DartString.literal(message), compiler); | 1543 graph.addConstantString(new ast.DartString.literal(message), compiler); |
| 1630 MethodElement element = helpers.assertIsSubtype; | 1544 MethodElement element = helpers.assertIsSubtype; |
| 1631 var inputs = <HInstruction>[ | 1545 var inputs = <HInstruction>[ |
| 1632 subtypeInstruction, | 1546 subtypeInstruction, |
| 1633 supertypeInstruction, | 1547 supertypeInstruction, |
| 1634 messageInstruction | 1548 messageInstruction |
| 1635 ]; | 1549 ]; |
| 1636 HInstruction assertIsSubtype = | 1550 HInstruction assertIsSubtype = |
| 1637 new HInvokeStatic(element, inputs, subtypeInstruction.instructionType); | 1551 new HInvokeStatic(element, inputs, subtypeInstruction.instructionType); |
| 1638 registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); | 1552 registry?.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); |
| 1639 add(assertIsSubtype); | 1553 add(assertIsSubtype); |
| 1640 } | 1554 } |
| 1641 | 1555 |
| 1642 HGraph closeFunction() { | 1556 HGraph closeFunction() { |
| 1643 // TODO(kasperl): Make this goto an implicit return. | 1557 // TODO(kasperl): Make this goto an implicit return. |
| 1644 if (!isAborted()) closeAndGotoExit(new HGoto()); | 1558 if (!isAborted()) closeAndGotoExit(new HGoto()); |
| 1645 graph.finalize(); | 1559 graph.finalize(); |
| 1646 return graph; | 1560 return graph; |
| 1647 } | 1561 } |
| 1648 | 1562 |
| 1649 void pushWithPosition(HInstruction instruction, ast.Node node) { | 1563 void pushWithPosition(HInstruction instruction, ast.Node node) { |
| 1650 push(attachPosition(instruction, node)); | 1564 push(attachPosition(instruction, node)); |
| 1651 } | 1565 } |
| 1652 | 1566 |
| 1567 /// Pops the most recent instruction from the stack and 'boolifies' it. |
| 1568 /// |
| 1569 /// Boolification is checking if the value is '=== true'. |
| 1653 @override | 1570 @override |
| 1654 HInstruction popBoolified() { | 1571 HInstruction popBoolified() { |
| 1655 HInstruction value = pop(); | 1572 HInstruction value = pop(); |
| 1656 if (_checkOrTrustTypes) { | 1573 if (typeVerifier.checkOrTrustTypes) { |
| 1657 return potentiallyCheckOrTrustType(value, compiler.coreTypes.boolType, | 1574 return typeVerifier.potentiallyCheckOrTrustType( |
| 1575 value, compiler.coreTypes.boolType, |
| 1658 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); | 1576 kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK); |
| 1659 } | 1577 } |
| 1660 HInstruction result = new HBoolify(value, backend.boolType); | 1578 HInstruction result = new HBoolify(value, backend.boolType); |
| 1661 add(result); | 1579 add(result); |
| 1662 return result; | 1580 return result; |
| 1663 } | 1581 } |
| 1664 | 1582 |
| 1665 HInstruction attachPosition(HInstruction target, ast.Node node) { | 1583 HInstruction attachPosition(HInstruction target, ast.Node node) { |
| 1666 if (node != null) { | 1584 if (node != null) { |
| 1667 target.sourceInformation = sourceInformationBuilder.buildGeneric(node); | 1585 target.sourceInformation = sourceInformationBuilder.buildGeneric(node); |
| (...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2438 } | 2356 } |
| 2439 assert(invariant( | 2357 assert(invariant( |
| 2440 location, send == null || !Elements.isInstanceSend(send, elements), | 2358 location, send == null || !Elements.isInstanceSend(send, elements), |
| 2441 message: "Unexpected non instance setter: $element.")); | 2359 message: "Unexpected non instance setter: $element.")); |
| 2442 if (Elements.isStaticOrTopLevelField(element)) { | 2360 if (Elements.isStaticOrTopLevelField(element)) { |
| 2443 if (element.isSetter) { | 2361 if (element.isSetter) { |
| 2444 pushInvokeStatic(location, element, <HInstruction>[value]); | 2362 pushInvokeStatic(location, element, <HInstruction>[value]); |
| 2445 pop(); | 2363 pop(); |
| 2446 } else { | 2364 } else { |
| 2447 FieldElement field = element; | 2365 FieldElement field = element; |
| 2448 value = potentiallyCheckOrTrustType(value, field.type); | 2366 value = typeVerifier.potentiallyCheckOrTrustType(value, field.type); |
| 2449 addWithPosition(new HStaticStore(field, value), location); | 2367 addWithPosition(new HStaticStore(field, value), location); |
| 2450 } | 2368 } |
| 2451 stack.add(value); | 2369 stack.add(value); |
| 2452 } else if (Elements.isError(element)) { | 2370 } else if (Elements.isError(element)) { |
| 2453 generateNoSuchSetter(location, element, send == null ? null : value); | 2371 generateNoSuchSetter(location, element, send == null ? null : value); |
| 2454 } else if (Elements.isMalformed(element)) { | 2372 } else if (Elements.isMalformed(element)) { |
| 2455 // TODO(ahe): Do something like [generateWrongArgumentCountError]. | 2373 // TODO(ahe): Do something like [generateWrongArgumentCountError]. |
| 2456 stack.add(graph.addConstantNull(compiler)); | 2374 stack.add(graph.addConstantNull(compiler)); |
| 2457 } else { | 2375 } else { |
| 2458 stack.add(value); | 2376 stack.add(value); |
| 2459 LocalElement local = element; | 2377 LocalElement local = element; |
| 2460 // If the value does not already have a name, give it here. | 2378 // If the value does not already have a name, give it here. |
| 2461 if (value.sourceElement == null) { | 2379 if (value.sourceElement == null) { |
| 2462 value.sourceElement = local; | 2380 value.sourceElement = local; |
| 2463 } | 2381 } |
| 2464 HInstruction checkedOrTrusted = | 2382 HInstruction checkedOrTrusted = |
| 2465 potentiallyCheckOrTrustType(value, local.type); | 2383 typeVerifier.potentiallyCheckOrTrustType(value, local.type); |
| 2466 if (!identical(checkedOrTrusted, value)) { | 2384 if (!identical(checkedOrTrusted, value)) { |
| 2467 pop(); | 2385 pop(); |
| 2468 stack.add(checkedOrTrusted); | 2386 stack.add(checkedOrTrusted); |
| 2469 } | 2387 } |
| 2470 | 2388 |
| 2471 localsHandler.updateLocal(local, checkedOrTrusted, | 2389 localsHandler.updateLocal(local, checkedOrTrusted, |
| 2472 sourceInformation: | 2390 sourceInformation: |
| 2473 sourceInformationBuilder.buildAssignment(location)); | 2391 sourceInformationBuilder.buildAssignment(location)); |
| 2474 } | 2392 } |
| 2475 } | 2393 } |
| 2476 | 2394 |
| 2477 HInstruction invokeInterceptor(HInstruction receiver) { | 2395 HInstruction invokeInterceptor(HInstruction receiver) { |
| 2478 HInterceptor interceptor = new HInterceptor(receiver, backend.nonNullType); | 2396 HInterceptor interceptor = new HInterceptor(receiver, backend.nonNullType); |
| 2479 add(interceptor); | 2397 add(interceptor); |
| 2480 return interceptor; | 2398 return interceptor; |
| 2481 } | 2399 } |
| 2482 | 2400 |
| 2483 HLiteralList buildLiteralList(List<HInstruction> inputs) { | 2401 HLiteralList buildLiteralList(List<HInstruction> inputs) { |
| 2484 return new HLiteralList(inputs, backend.extendableArrayType); | 2402 return new HLiteralList(inputs, backend.extendableArrayType); |
| 2485 } | 2403 } |
| 2486 | 2404 |
| 2487 HInstruction buildTypeArgumentRepresentations(DartType type) { | |
| 2488 assert(!type.isTypeVariable); | |
| 2489 // Compute the representation of the type arguments, including access | |
| 2490 // to the runtime type information for type variables as instructions. | |
| 2491 assert(type.element.isClass); | |
| 2492 InterfaceType interface = type; | |
| 2493 List<HInstruction> inputs = <HInstruction>[]; | |
| 2494 for (DartType argument in interface.typeArguments) { | |
| 2495 inputs.add(analyzeTypeArgument(argument)); | |
| 2496 } | |
| 2497 HInstruction representation = new HTypeInfoExpression( | |
| 2498 TypeInfoExpressionKind.INSTANCE, | |
| 2499 interface.element.thisType, | |
| 2500 inputs, | |
| 2501 backend.dynamicType); | |
| 2502 return representation; | |
| 2503 } | |
| 2504 | |
| 2505 @override | 2405 @override |
| 2506 void visitAs(ast.Send node, ast.Node expression, DartType type, _) { | 2406 void visitAs(ast.Send node, ast.Node expression, DartType type, _) { |
| 2507 HInstruction expressionInstruction = visitAndPop(expression); | 2407 HInstruction expressionInstruction = visitAndPop(expression); |
| 2508 if (type.isMalformed) { | 2408 if (type.isMalformed) { |
| 2509 if (type is MalformedType) { | 2409 if (type is MalformedType) { |
| 2510 ErroneousElement element = type.element; | 2410 ErroneousElement element = type.element; |
| 2511 generateTypeError(node, element.message); | 2411 generateTypeError(node, element.message); |
| 2512 } else { | 2412 } else { |
| 2513 assert(type is MethodTypeVariableType); | 2413 assert(type is MethodTypeVariableType); |
| 2514 stack.add(expressionInstruction); | 2414 stack.add(expressionInstruction); |
| 2515 } | 2415 } |
| 2516 } else { | 2416 } else { |
| 2517 HInstruction converted = buildTypeConversion(expressionInstruction, | 2417 HInstruction converted = typeVerifier.buildTypeConversion( |
| 2518 localsHandler.substInContext(type), HTypeConversion.CAST_TYPE_CHECK); | 2418 expressionInstruction, localsHandler.substInContext(type), |
| 2419 HTypeConversion.CAST_TYPE_CHECK); |
| 2519 if (converted != expressionInstruction) add(converted); | 2420 if (converted != expressionInstruction) add(converted); |
| 2520 stack.add(converted); | 2421 stack.add(converted); |
| 2521 } | 2422 } |
| 2522 } | 2423 } |
| 2523 | 2424 |
| 2524 @override | 2425 @override |
| 2525 void visitIs(ast.Send node, ast.Node expression, DartType type, _) { | 2426 void visitIs(ast.Send node, ast.Node expression, DartType type, _) { |
| 2526 HInstruction expressionInstruction = visitAndPop(expression); | 2427 HInstruction expressionInstruction = visitAndPop(expression); |
| 2527 push(buildIsNode(node, type, expressionInstruction)); | 2428 push(buildIsNode(node, type, expressionInstruction)); |
| 2528 } | 2429 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2554 } else if (type.isFunctionType) { | 2455 } else if (type.isFunctionType) { |
| 2555 List arguments = [buildFunctionType(type), expression]; | 2456 List arguments = [buildFunctionType(type), expression]; |
| 2556 pushInvokeDynamic( | 2457 pushInvokeDynamic( |
| 2557 node, | 2458 node, |
| 2558 new Selector.call(new PrivateName('_isTest', helpers.jsHelperLibrary), | 2459 new Selector.call(new PrivateName('_isTest', helpers.jsHelperLibrary), |
| 2559 CallStructure.ONE_ARG), | 2460 CallStructure.ONE_ARG), |
| 2560 null, | 2461 null, |
| 2561 arguments); | 2462 arguments); |
| 2562 return new HIs.compound(type, expression, pop(), backend.boolType); | 2463 return new HIs.compound(type, expression, pop(), backend.boolType); |
| 2563 } else if (type.isTypeVariable) { | 2464 } else if (type.isTypeVariable) { |
| 2564 HInstruction runtimeType = addTypeVariableReference(type); | 2465 HInstruction runtimeType = typeVerifier.addTypeVariableReference( |
| 2466 type, sourceElement); |
| 2565 Element helper = helpers.checkSubtypeOfRuntimeType; | 2467 Element helper = helpers.checkSubtypeOfRuntimeType; |
| 2566 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; | 2468 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; |
| 2567 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType); | 2469 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType); |
| 2568 HInstruction call = pop(); | 2470 HInstruction call = pop(); |
| 2569 return new HIs.variable(type, expression, call, backend.boolType); | 2471 return new HIs.variable(type, expression, call, backend.boolType); |
| 2570 } else if (RuntimeTypes.hasTypeArguments(type)) { | 2472 } else if (RuntimeTypes.hasTypeArguments(type)) { |
| 2571 ClassElement element = type.element; | 2473 ClassElement element = type.element; |
| 2572 Element helper = helpers.checkSubtype; | 2474 Element helper = helpers.checkSubtype; |
| 2573 HInstruction representations = buildTypeArgumentRepresentations(type); | 2475 HInstruction representations = |
| 2476 typeVerifier.buildTypeArgumentRepresentations(type, sourceElement); |
| 2574 add(representations); | 2477 add(representations); |
| 2575 js.Name operator = backend.namer.operatorIs(element); | 2478 js.Name operator = backend.namer.operatorIs(element); |
| 2576 HInstruction isFieldName = addConstantStringFromName(operator); | 2479 HInstruction isFieldName = addConstantStringFromName(operator); |
| 2577 HInstruction asFieldName = compiler.closedWorld | 2480 HInstruction asFieldName = compiler.closedWorld |
| 2578 .hasAnyStrictSubtype(element) | 2481 .hasAnyStrictSubtype(element) |
| 2579 ? addConstantStringFromName(backend.namer.substitutionName(element)) | 2482 ? addConstantStringFromName(backend.namer.substitutionName(element)) |
| 2580 : graph.addConstantNull(compiler); | 2483 : graph.addConstantNull(compiler); |
| 2581 List<HInstruction> inputs = <HInstruction>[ | 2484 List<HInstruction> inputs = <HInstruction>[ |
| 2582 expression, | 2485 expression, |
| 2583 isFieldName, | 2486 isFieldName, |
| 2584 representations, | 2487 representations, |
| 2585 asFieldName | 2488 asFieldName |
| 2586 ]; | 2489 ]; |
| 2587 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType); | 2490 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType); |
| 2588 HInstruction call = pop(); | 2491 HInstruction call = pop(); |
| 2589 return new HIs.compound(type, expression, call, backend.boolType); | 2492 return new HIs.compound(type, expression, call, backend.boolType); |
| 2590 } else { | 2493 } else { |
| 2591 if (backend.hasDirectCheckFor(type)) { | 2494 if (backend.hasDirectCheckFor(type)) { |
| 2592 return new HIs.direct(type, expression, backend.boolType); | 2495 return new HIs.direct(type, expression, backend.boolType); |
| 2593 } | 2496 } |
| 2594 // The interceptor is not always needed. It is removed by optimization | 2497 // The interceptor is not always needed. It is removed by optimization |
| 2595 // when the receiver type or tested type permit. | 2498 // when the receiver type or tested type permit. |
| 2596 return new HIs.raw( | 2499 return new HIs.raw( |
| 2597 type, expression, invokeInterceptor(expression), backend.boolType); | 2500 type, expression, invokeInterceptor(expression), backend.boolType); |
| 2598 } | 2501 } |
| 2599 } | 2502 } |
| 2600 | 2503 |
| 2601 HInstruction buildFunctionType(FunctionType type) { | |
| 2602 type.accept(new TypeBuilder(compiler.closedWorld), this); | |
| 2603 return pop(); | |
| 2604 } | |
| 2605 | |
| 2606 void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) { | 2504 void addDynamicSendArgumentsToList(ast.Send node, List<HInstruction> list) { |
| 2607 CallStructure callStructure = elements.getSelector(node).callStructure; | 2505 CallStructure callStructure = elements.getSelector(node).callStructure; |
| 2608 if (callStructure.namedArgumentCount == 0) { | 2506 if (callStructure.namedArgumentCount == 0) { |
| 2609 addGenericSendArgumentsToList(node.arguments, list); | 2507 addGenericSendArgumentsToList(node.arguments, list); |
| 2610 } else { | 2508 } else { |
| 2611 // Visit positional arguments and add them to the list. | 2509 // Visit positional arguments and add them to the list. |
| 2612 Link<ast.Node> arguments = node.arguments; | 2510 Link<ast.Node> arguments = node.arguments; |
| 2613 int positionalArgumentCount = callStructure.positionalArgumentCount; | 2511 int positionalArgumentCount = callStructure.positionalArgumentCount; |
| 2614 for (int i = 0; | 2512 for (int i = 0; |
| 2615 i < positionalArgumentCount; | 2513 i < positionalArgumentCount; |
| (...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3382 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { | 3280 bool needsSubstitutionForTypeVariableAccess(ClassElement cls) { |
| 3383 ClosedWorld closedWorld = compiler.closedWorld; | 3281 ClosedWorld closedWorld = compiler.closedWorld; |
| 3384 if (closedWorld.isUsedAsMixin(cls)) return true; | 3282 if (closedWorld.isUsedAsMixin(cls)) return true; |
| 3385 | 3283 |
| 3386 return compiler.closedWorld.anyStrictSubclassOf(cls, | 3284 return compiler.closedWorld.anyStrictSubclassOf(cls, |
| 3387 (ClassElement subclass) { | 3285 (ClassElement subclass) { |
| 3388 return !rti.isTrivialSubstitution(subclass, cls); | 3286 return !rti.isTrivialSubstitution(subclass, cls); |
| 3389 }); | 3287 }); |
| 3390 } | 3288 } |
| 3391 | 3289 |
| 3392 /** | |
| 3393 * Generate code to extract the type argument from the object. | |
| 3394 */ | |
| 3395 HInstruction readTypeVariable(TypeVariableType variable, | |
| 3396 {SourceInformation sourceInformation}) { | |
| 3397 assert(sourceElement.isInstanceMember); | |
| 3398 assert(variable is! MethodTypeVariableType); | |
| 3399 HInstruction target = localsHandler.readThis(); | |
| 3400 push(new HTypeInfoReadVariable(variable, target, backend.dynamicType) | |
| 3401 ..sourceInformation = sourceInformation); | |
| 3402 return pop(); | |
| 3403 } | |
| 3404 | |
| 3405 // TODO(karlklose): this is needed to avoid a bug where the resolved type is | |
| 3406 // not stored on a type annotation in the closure translator. Remove when | |
| 3407 // fixed. | |
| 3408 bool hasDirectLocal(Local local) { | |
| 3409 return !localsHandler.isAccessedDirectly(local) || | |
| 3410 localsHandler.directLocals[local] != null; | |
| 3411 } | |
| 3412 | |
| 3413 /** | |
| 3414 * Helper to create an instruction that gets the value of a type variable. | |
| 3415 */ | |
| 3416 HInstruction addTypeVariableReference(TypeVariableType type, | |
| 3417 {SourceInformation sourceInformation}) { | |
| 3418 assert(assertTypeInContext(type)); | |
| 3419 if (type is MethodTypeVariableType) { | |
| 3420 return graph.addConstantNull(compiler); | |
| 3421 } | |
| 3422 Element member = sourceElement; | |
| 3423 bool isClosure = member.enclosingElement.isClosure; | |
| 3424 if (isClosure) { | |
| 3425 ClosureClassElement closureClass = member.enclosingElement; | |
| 3426 member = closureClass.methodElement; | |
| 3427 member = member.outermostEnclosingMemberOrTopLevel; | |
| 3428 } | |
| 3429 bool isInConstructorContext = | |
| 3430 member.isConstructor || member.isGenerativeConstructorBody; | |
| 3431 Local typeVariableLocal = localsHandler.getTypeVariableAsLocal(type); | |
| 3432 if (isClosure) { | |
| 3433 if (member.isFactoryConstructor || | |
| 3434 (isInConstructorContext && hasDirectLocal(typeVariableLocal))) { | |
| 3435 // The type variable is used from a closure in a factory constructor. | |
| 3436 // The value of the type argument is stored as a local on the closure | |
| 3437 // itself. | |
| 3438 return localsHandler.readLocal(typeVariableLocal, | |
| 3439 sourceInformation: sourceInformation); | |
| 3440 } else if (member.isFunction || | |
| 3441 member.isGetter || | |
| 3442 member.isSetter || | |
| 3443 isInConstructorContext) { | |
| 3444 // The type variable is stored on the "enclosing object" and needs to be | |
| 3445 // accessed using the this-reference in the closure. | |
| 3446 return readTypeVariable(type, sourceInformation: sourceInformation); | |
| 3447 } else { | |
| 3448 assert(member.isField); | |
| 3449 // The type variable is stored in a parameter of the method. | |
| 3450 return localsHandler.readLocal(typeVariableLocal); | |
| 3451 } | |
| 3452 } else if (isInConstructorContext || | |
| 3453 // When [member] is a field, we can be either | |
| 3454 // generating a checked setter or inlining its | |
| 3455 // initializer in a constructor. An initializer is | |
| 3456 // never built standalone, so in that case [target] is not | |
| 3457 // the [member] itself. | |
| 3458 (member.isField && member != target)) { | |
| 3459 // The type variable is stored in a parameter of the method. | |
| 3460 return localsHandler.readLocal(typeVariableLocal, | |
| 3461 sourceInformation: sourceInformation); | |
| 3462 } else if (member.isInstanceMember) { | |
| 3463 // The type variable is stored on the object. | |
| 3464 return readTypeVariable(type, sourceInformation: sourceInformation); | |
| 3465 } else { | |
| 3466 reporter.internalError( | |
| 3467 type.element, 'Unexpected type variable in static context.'); | |
| 3468 return null; | |
| 3469 } | |
| 3470 } | |
| 3471 | |
| 3472 HInstruction analyzeTypeArgument(DartType argument, | |
| 3473 {SourceInformation sourceInformation}) { | |
| 3474 assert(assertTypeInContext(argument)); | |
| 3475 argument = argument.unaliased; | |
| 3476 if (argument.treatAsDynamic) { | |
| 3477 // Represent [dynamic] as [null]. | |
| 3478 return graph.addConstantNull(compiler); | |
| 3479 } | |
| 3480 | |
| 3481 if (argument.isTypeVariable) { | |
| 3482 return addTypeVariableReference(argument, | |
| 3483 sourceInformation: sourceInformation); | |
| 3484 } | |
| 3485 | |
| 3486 List<HInstruction> inputs = <HInstruction>[]; | |
| 3487 argument.forEachTypeVariable((variable) { | |
| 3488 if (variable is! MethodTypeVariableType) { | |
| 3489 inputs.add(analyzeTypeArgument(variable)); | |
| 3490 } | |
| 3491 }); | |
| 3492 HInstruction result = new HTypeInfoExpression( | |
| 3493 TypeInfoExpressionKind.COMPLETE, argument, inputs, backend.dynamicType) | |
| 3494 ..sourceInformation = sourceInformation; | |
| 3495 add(result); | |
| 3496 return result; | |
| 3497 } | |
| 3498 | |
| 3499 HInstruction handleListConstructor( | 3290 HInstruction handleListConstructor( |
| 3500 InterfaceType type, ast.Node currentNode, HInstruction newObject) { | 3291 InterfaceType type, ast.Node currentNode, HInstruction newObject) { |
| 3501 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { | 3292 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { |
| 3502 return newObject; | 3293 return newObject; |
| 3503 } | 3294 } |
| 3504 List<HInstruction> inputs = <HInstruction>[]; | 3295 List<HInstruction> inputs = <HInstruction>[]; |
| 3505 type = localsHandler.substInContext(type); | 3296 type = localsHandler.substInContext(type); |
| 3506 type.typeArguments.forEach((DartType argument) { | 3297 type.typeArguments.forEach((DartType argument) { |
| 3507 inputs.add(analyzeTypeArgument(argument)); | 3298 inputs.add(typeVerifier.analyzeTypeArgument(argument, sourceElement)); |
| 3508 }); | 3299 }); |
| 3509 // TODO(15489): Register at codegen. | 3300 // TODO(15489): Register at codegen. |
| 3510 registry?.registerInstantiation(type); | 3301 registry?.registerInstantiation(type); |
| 3511 return callSetRuntimeTypeInfoWithTypeArguments( | 3302 return callSetRuntimeTypeInfoWithTypeArguments( |
| 3512 type.element, inputs, newObject); | 3303 type.element, inputs, newObject); |
| 3513 } | 3304 } |
| 3514 | 3305 |
| 3515 HInstruction callSetRuntimeTypeInfoWithTypeArguments(ClassElement element, | 3306 HInstruction callSetRuntimeTypeInfoWithTypeArguments(ClassElement element, |
| 3516 List<HInstruction> rtiInputs, HInstruction newObject) { | 3307 List<HInstruction> rtiInputs, HInstruction newObject) { |
| 3517 if (!backend.classNeedsRti(element)) { | 3308 if (!backend.classNeedsRti(element)) { |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3745 if (backend.classNeedsRti(coreClasses.listClass) && | 3536 if (backend.classNeedsRti(coreClasses.listClass) && |
| 3746 (isFixedListConstructorCall || | 3537 (isFixedListConstructorCall || |
| 3747 isGrowableListConstructorCall || | 3538 isGrowableListConstructorCall || |
| 3748 isJSArrayTypedConstructor)) { | 3539 isJSArrayTypedConstructor)) { |
| 3749 newInstance = handleListConstructor(type, send, pop()); | 3540 newInstance = handleListConstructor(type, send, pop()); |
| 3750 stack.add(newInstance); | 3541 stack.add(newInstance); |
| 3751 } | 3542 } |
| 3752 | 3543 |
| 3753 // Finally, if we called a redirecting factory constructor, check the type. | 3544 // Finally, if we called a redirecting factory constructor, check the type. |
| 3754 if (isRedirected) { | 3545 if (isRedirected) { |
| 3755 HInstruction checked = potentiallyCheckOrTrustType(newInstance, type); | 3546 HInstruction checked = typeVerifier.potentiallyCheckOrTrustType( |
| 3547 newInstance, type); |
| 3756 if (checked != newInstance) { | 3548 if (checked != newInstance) { |
| 3757 pop(); | 3549 pop(); |
| 3758 stack.add(checked); | 3550 stack.add(checked); |
| 3759 } | 3551 } |
| 3760 } | 3552 } |
| 3761 } | 3553 } |
| 3762 | 3554 |
| 3763 void potentiallyAddTypeArguments( | 3555 void potentiallyAddTypeArguments( |
| 3764 List<HInstruction> inputs, ClassElement cls, InterfaceType expectedType, | 3556 List<HInstruction> inputs, ClassElement cls, InterfaceType expectedType, |
| 3765 {SourceInformation sourceInformation}) { | 3557 {SourceInformation sourceInformation}) { |
| 3766 if (!backend.classNeedsRti(cls)) return; | 3558 if (!backend.classNeedsRti(cls)) return; |
| 3767 assert(cls.typeVariables.length == expectedType.typeArguments.length); | 3559 assert(cls.typeVariables.length == expectedType.typeArguments.length); |
| 3768 expectedType.typeArguments.forEach((DartType argument) { | 3560 expectedType.typeArguments.forEach((DartType argument) { |
| 3769 inputs.add( | 3561 inputs.add( |
| 3770 analyzeTypeArgument(argument, sourceInformation: sourceInformation)); | 3562 typeVerifier.analyzeTypeArgument(argument, sourceElement, |
| 3563 sourceInformation: sourceInformation)); |
| 3771 }); | 3564 }); |
| 3772 } | 3565 } |
| 3773 | 3566 |
| 3774 /// In checked mode checks the [type] of [node] to be well-bounded. The method | 3567 /// In checked mode checks the [type] of [node] to be well-bounded. The method |
| 3775 /// returns [:true:] if an error can be statically determined. | 3568 /// returns [:true:] if an error can be statically determined. |
| 3776 bool checkTypeVariableBounds(ast.NewExpression node, InterfaceType type) { | 3569 bool checkTypeVariableBounds(ast.NewExpression node, InterfaceType type) { |
| 3777 if (!compiler.options.enableTypeAssertions) return false; | 3570 if (!compiler.options.enableTypeAssertions) return false; |
| 3778 | 3571 |
| 3779 Map<DartType, Set<DartType>> seenChecksMap = | 3572 Map<DartType, Set<DartType>> seenChecksMap = |
| 3780 new Map<DartType, Set<DartType>>(); | 3573 new Map<DartType, Set<DartType>>(); |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4032 /// Generate the literal for [typeVariable] in the current context. | 3825 /// Generate the literal for [typeVariable] in the current context. |
| 4033 void generateTypeVariableLiteral( | 3826 void generateTypeVariableLiteral( |
| 4034 ast.Send node, TypeVariableType typeVariable) { | 3827 ast.Send node, TypeVariableType typeVariable) { |
| 4035 // GENERIC_METHODS: This provides thin support for method type variables | 3828 // GENERIC_METHODS: This provides thin support for method type variables |
| 4036 // by treating them as malformed when evaluated as a literal. For full | 3829 // by treating them as malformed when evaluated as a literal. For full |
| 4037 // support of generic methods this must be revised. | 3830 // support of generic methods this must be revised. |
| 4038 if (typeVariable is MethodTypeVariableType) { | 3831 if (typeVariable is MethodTypeVariableType) { |
| 4039 generateTypeError(node, "Method type variables are not reified"); | 3832 generateTypeError(node, "Method type variables are not reified"); |
| 4040 } else { | 3833 } else { |
| 4041 DartType type = localsHandler.substInContext(typeVariable); | 3834 DartType type = localsHandler.substInContext(typeVariable); |
| 4042 HInstruction value = analyzeTypeArgument(type, | 3835 HInstruction value = typeVerifier.analyzeTypeArgument(type, sourceElement, |
| 4043 sourceInformation: sourceInformationBuilder.buildGet(node)); | 3836 sourceInformation: sourceInformationBuilder.buildGet(node)); |
| 4044 pushInvokeStatic(node, helpers.runtimeTypeToString, [value], | 3837 pushInvokeStatic(node, helpers.runtimeTypeToString, [value], |
| 4045 typeMask: backend.stringType); | 3838 typeMask: backend.stringType); |
| 4046 pushInvokeStatic(node, helpers.createRuntimeType, [pop()]); | 3839 pushInvokeStatic(node, helpers.createRuntimeType, [pop()]); |
| 4047 } | 3840 } |
| 4048 } | 3841 } |
| 4049 | 3842 |
| 4050 /// Generate a call to a type literal. | 3843 /// Generate a call to a type literal. |
| 4051 void generateTypeLiteralCall(ast.Send node) { | 3844 void generateTypeLiteralCall(ast.Send node) { |
| 4052 // This send is of the form 'e(...)', where e is resolved to a type | 3845 // This send is of the form 'e(...)', where e is resolved to a type |
| (...skipping 1305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5358 } | 5151 } |
| 5359 } | 5152 } |
| 5360 | 5153 |
| 5361 ClassElement targetClass = targetConstructor.enclosingClass; | 5154 ClassElement targetClass = targetConstructor.enclosingClass; |
| 5362 if (backend.classNeedsRti(targetClass)) { | 5155 if (backend.classNeedsRti(targetClass)) { |
| 5363 ClassElement cls = redirectingConstructor.enclosingClass; | 5156 ClassElement cls = redirectingConstructor.enclosingClass; |
| 5364 InterfaceType targetType = | 5157 InterfaceType targetType = |
| 5365 redirectingConstructor.computeEffectiveTargetType(cls.thisType); | 5158 redirectingConstructor.computeEffectiveTargetType(cls.thisType); |
| 5366 targetType = localsHandler.substInContext(targetType); | 5159 targetType = localsHandler.substInContext(targetType); |
| 5367 targetType.typeArguments.forEach((DartType argument) { | 5160 targetType.typeArguments.forEach((DartType argument) { |
| 5368 inputs.add(analyzeTypeArgument(argument)); | 5161 inputs.add(typeVerifier.analyzeTypeArgument(argument, sourceElement)); |
| 5369 }); | 5162 }); |
| 5370 } | 5163 } |
| 5371 pushInvokeStatic(node, targetConstructor.declaration, inputs); | 5164 pushInvokeStatic(node, targetConstructor.declaration, inputs); |
| 5372 HInstruction value = pop(); | 5165 HInstruction value = pop(); |
| 5373 emitReturn(value, node); | 5166 emitReturn(value, node); |
| 5374 } | 5167 } |
| 5375 | 5168 |
| 5376 /// Returns true if the [type] is a valid return type for an asynchronous | 5169 /// Returns true if the [type] is a valid return type for an asynchronous |
| 5377 /// function. | 5170 /// function. |
| 5378 /// | 5171 /// |
| (...skipping 29 matching lines...) Expand all Loading... |
| 5408 if (isBuildingAsyncFunction) { | 5201 if (isBuildingAsyncFunction) { |
| 5409 if (compiler.options.enableTypeAssertions && | 5202 if (compiler.options.enableTypeAssertions && |
| 5410 !isValidAsyncReturnType(returnType)) { | 5203 !isValidAsyncReturnType(returnType)) { |
| 5411 String message = "Async function returned a Future, " | 5204 String message = "Async function returned a Future, " |
| 5412 "was declared to return a $returnType."; | 5205 "was declared to return a $returnType."; |
| 5413 generateTypeError(node, message); | 5206 generateTypeError(node, message); |
| 5414 pop(); | 5207 pop(); |
| 5415 return; | 5208 return; |
| 5416 } | 5209 } |
| 5417 } else { | 5210 } else { |
| 5418 value = potentiallyCheckOrTrustType(value, returnType); | 5211 value = typeVerifier.potentiallyCheckOrTrustType(value, returnType); |
| 5419 } | 5212 } |
| 5420 } | 5213 } |
| 5421 | 5214 |
| 5422 handleInTryStatement(); | 5215 handleInTryStatement(); |
| 5423 emitReturn(value, node); | 5216 emitReturn(value, node); |
| 5424 } | 5217 } |
| 5425 | 5218 |
| 5426 visitThrow(ast.Throw node) { | 5219 visitThrow(ast.Throw node) { |
| 5427 visitThrowExpression(node.expression); | 5220 visitThrowExpression(node.expression); |
| 5428 if (isReachable) { | 5221 if (isReachable) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5470 } | 5263 } |
| 5471 } | 5264 } |
| 5472 | 5265 |
| 5473 HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) { | 5266 HInstruction setRtiIfNeeded(HInstruction object, ast.Node node) { |
| 5474 InterfaceType type = localsHandler.substInContext(elements.getType(node)); | 5267 InterfaceType type = localsHandler.substInContext(elements.getType(node)); |
| 5475 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { | 5268 if (!backend.classNeedsRti(type.element) || type.treatAsRaw) { |
| 5476 return object; | 5269 return object; |
| 5477 } | 5270 } |
| 5478 List<HInstruction> arguments = <HInstruction>[]; | 5271 List<HInstruction> arguments = <HInstruction>[]; |
| 5479 for (DartType argument in type.typeArguments) { | 5272 for (DartType argument in type.typeArguments) { |
| 5480 arguments.add(analyzeTypeArgument(argument)); | 5273 arguments.add(typeVerifier.analyzeTypeArgument(argument, sourceElement)); |
| 5481 } | 5274 } |
| 5482 // TODO(15489): Register at codegen. | 5275 // TODO(15489): Register at codegen. |
| 5483 registry?.registerInstantiation(type); | 5276 registry?.registerInstantiation(type); |
| 5484 return callSetRuntimeTypeInfoWithTypeArguments( | 5277 return callSetRuntimeTypeInfoWithTypeArguments( |
| 5485 type.element, arguments, object); | 5278 type.element, arguments, object); |
| 5486 } | 5279 } |
| 5487 | 5280 |
| 5488 visitLiteralList(ast.LiteralList node) { | 5281 visitLiteralList(ast.LiteralList node) { |
| 5489 HInstruction instruction; | 5282 HInstruction instruction; |
| 5490 | 5283 |
| (...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5918 InterfaceType type = elements.getType(node); | 5711 InterfaceType type = elements.getType(node); |
| 5919 InterfaceType expectedType = | 5712 InterfaceType expectedType = |
| 5920 functionElement.computeEffectiveTargetType(type); | 5713 functionElement.computeEffectiveTargetType(type); |
| 5921 expectedType = localsHandler.substInContext(expectedType); | 5714 expectedType = localsHandler.substInContext(expectedType); |
| 5922 | 5715 |
| 5923 ClassElement cls = constructor.enclosingClass; | 5716 ClassElement cls = constructor.enclosingClass; |
| 5924 | 5717 |
| 5925 if (backend.classNeedsRti(cls)) { | 5718 if (backend.classNeedsRti(cls)) { |
| 5926 List<HInstruction> typeInputs = <HInstruction>[]; | 5719 List<HInstruction> typeInputs = <HInstruction>[]; |
| 5927 expectedType.typeArguments.forEach((DartType argument) { | 5720 expectedType.typeArguments.forEach((DartType argument) { |
| 5928 typeInputs.add(analyzeTypeArgument(argument)); | 5721 typeInputs.add(typeVerifier.analyzeTypeArgument( |
| 5722 argument, sourceElement)); |
| 5929 }); | 5723 }); |
| 5930 | 5724 |
| 5931 // We lift this common call pattern into a helper function to save space | 5725 // We lift this common call pattern into a helper function to save space |
| 5932 // in the output. | 5726 // in the output. |
| 5933 if (typeInputs.every((HInstruction input) => input.isNull())) { | 5727 if (typeInputs.every((HInstruction input) => input.isNull())) { |
| 5934 if (listInputs.isEmpty) { | 5728 if (listInputs.isEmpty) { |
| 5935 constructor = helpers.mapLiteralUntypedEmptyMaker; | 5729 constructor = helpers.mapLiteralUntypedEmptyMaker; |
| 5936 } else { | 5730 } else { |
| 5937 constructor = helpers.mapLiteralUntypedMaker; | 5731 constructor = helpers.mapLiteralUntypedMaker; |
| 5938 } | 5732 } |
| (...skipping 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7017 | 6811 |
| 7018 void visitTypeVariableType(TypeVariableType type, SsaBuilder builder) { | 6812 void visitTypeVariableType(TypeVariableType type, SsaBuilder builder) { |
| 7019 ClassElement cls = builder.backend.helpers.RuntimeType; | 6813 ClassElement cls = builder.backend.helpers.RuntimeType; |
| 7020 TypeMask instructionType = new TypeMask.subclass(cls, closedWorld); | 6814 TypeMask instructionType = new TypeMask.subclass(cls, closedWorld); |
| 7021 if (!builder.sourceElement.enclosingElement.isClosure && | 6815 if (!builder.sourceElement.enclosingElement.isClosure && |
| 7022 builder.sourceElement.isInstanceMember) { | 6816 builder.sourceElement.isInstanceMember) { |
| 7023 HInstruction receiver = builder.localsHandler.readThis(); | 6817 HInstruction receiver = builder.localsHandler.readThis(); |
| 7024 builder.push(new HReadTypeVariable(type, receiver, instructionType)); | 6818 builder.push(new HReadTypeVariable(type, receiver, instructionType)); |
| 7025 } else { | 6819 } else { |
| 7026 builder.push(new HReadTypeVariable.noReceiver( | 6820 builder.push(new HReadTypeVariable.noReceiver( |
| 7027 type, builder.addTypeVariableReference(type), instructionType)); | 6821 type, builder.typeVerifier.addTypeVariableReference( |
| 6822 type, builder.sourceElement), instructionType)); |
| 7028 } | 6823 } |
| 7029 } | 6824 } |
| 7030 | 6825 |
| 7031 void visitFunctionType(FunctionType type, SsaBuilder builder) { | 6826 void visitFunctionType(FunctionType type, SsaBuilder builder) { |
| 7032 type.returnType.accept(this, builder); | 6827 type.returnType.accept(this, builder); |
| 7033 HInstruction returnType = builder.pop(); | 6828 HInstruction returnType = builder.pop(); |
| 7034 List<HInstruction> inputs = <HInstruction>[returnType]; | 6829 List<HInstruction> inputs = <HInstruction>[returnType]; |
| 7035 | 6830 |
| 7036 for (DartType parameter in type.parameterTypes) { | 6831 for (DartType parameter in type.parameterTypes) { |
| 7037 parameter.accept(this, builder); | 6832 parameter.accept(this, builder); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7086 if (unaliased is TypedefType) throw 'unable to unalias $type'; | 6881 if (unaliased is TypedefType) throw 'unable to unalias $type'; |
| 7087 unaliased.accept(this, builder); | 6882 unaliased.accept(this, builder); |
| 7088 } | 6883 } |
| 7089 | 6884 |
| 7090 void visitDynamicType(DynamicType type, SsaBuilder builder) { | 6885 void visitDynamicType(DynamicType type, SsaBuilder builder) { |
| 7091 JavaScriptBackend backend = builder.compiler.backend; | 6886 JavaScriptBackend backend = builder.compiler.backend; |
| 7092 ClassElement cls = backend.helpers.DynamicRuntimeType; | 6887 ClassElement cls = backend.helpers.DynamicRuntimeType; |
| 7093 builder.push(new HDynamicType(type, new TypeMask.exact(cls, closedWorld))); | 6888 builder.push(new HDynamicType(type, new TypeMask.exact(cls, closedWorld))); |
| 7094 } | 6889 } |
| 7095 } | 6890 } |
| OLD | NEW |