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 part of ssa; | 5 part of ssa; |
6 | 6 |
7 /** | 7 /** |
8 * A special element for the extra parameter taken by intercepted | 8 * A special element for the extra parameter taken by intercepted |
9 * methods. We need to override [Element.computeType] because our | 9 * methods. We need to override [Element.computeType] because our |
10 * optimizers may look at its declared type. | 10 * optimizers may look at its declared type. |
(...skipping 1426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1437 Map<Element, HInstruction> fieldValues) { | 1437 Map<Element, HInstruction> fieldValues) { |
1438 assert(invariant(constructor, constructor.isImplementation)); | 1438 assert(invariant(constructor, constructor.isImplementation)); |
1439 if (constructor.isSynthesized) { | 1439 if (constructor.isSynthesized) { |
1440 List<HInstruction> arguments = <HInstruction>[]; | 1440 List<HInstruction> arguments = <HInstruction>[]; |
1441 HInstruction compileArgument(Element element) { | 1441 HInstruction compileArgument(Element element) { |
1442 return localsHandler.readLocal(element); | 1442 return localsHandler.readLocal(element); |
1443 } | 1443 } |
1444 | 1444 |
1445 Element target = constructor.targetConstructor.implementation; | 1445 Element target = constructor.targetConstructor.implementation; |
1446 Selector.addForwardingElementArgumentsToList( | 1446 Selector.addForwardingElementArgumentsToList( |
1447 constructor, | 1447 constructor, |
1448 arguments, | 1448 arguments, |
1449 target, | 1449 target, |
1450 compileArgument, | 1450 compileArgument, |
1451 handleConstantForOptionalParameter, | 1451 handleConstantForOptionalParameter, |
1452 compiler); | 1452 compiler); |
1453 inlineSuperOrRedirect( | 1453 inlineSuperOrRedirect( |
1454 target, | 1454 target, |
1455 arguments, | 1455 arguments, |
1456 constructors, | 1456 constructors, |
1457 fieldValues, | 1457 fieldValues, |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1754 // Otherwise it is a lazy initializer which does not have parameters. | 1754 // Otherwise it is a lazy initializer which does not have parameters. |
1755 assert(element is VariableElement); | 1755 assert(element is VariableElement); |
1756 } | 1756 } |
1757 } | 1757 } |
1758 | 1758 |
1759 HInstruction buildTypeConversion(HInstruction original, | 1759 HInstruction buildTypeConversion(HInstruction original, |
1760 DartType type, | 1760 DartType type, |
1761 int kind) { | 1761 int kind) { |
1762 if (type == null) return original; | 1762 if (type == null) return original; |
1763 type = type.unalias(compiler); | 1763 type = type.unalias(compiler); |
1764 if (type.kind == TypeKind.INTERFACE && !type.isMalformed && !type.isRaw) { | 1764 if (type.kind == TypeKind.INTERFACE && !type.isRaw) { |
1765 HType subtype = new HType.subtype(type, compiler); | 1765 HType subtype = new HType.subtype(type, compiler); |
1766 HInstruction representations = buildTypeArgumentRepresentations(type); | 1766 HInstruction representations = buildTypeArgumentRepresentations(type); |
1767 add(representations); | 1767 add(representations); |
1768 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, | 1768 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, |
1769 original, representations); | 1769 original, representations); |
1770 } else if (type.kind == TypeKind.TYPE_VARIABLE) { | 1770 } else if (type.kind == TypeKind.TYPE_VARIABLE) { |
1771 HType subtype = original.instructionType; | 1771 HType subtype = original.instructionType; |
1772 HInstruction typeVariable = addTypeVariableReference(type); | 1772 HInstruction typeVariable = addTypeVariableReference(type); |
1773 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, | 1773 return new HTypeConversion.withTypeRepresentation(type, kind, subtype, |
1774 original, typeVariable); | 1774 original, typeVariable); |
(...skipping 988 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2763 visitBinary(left, op, right, elements.getSelector(node), node); | 2763 visitBinary(left, op, right, elements.getSelector(node), node); |
2764 } | 2764 } |
2765 } | 2765 } |
2766 | 2766 |
2767 void visitIsSend(Send node) { | 2767 void visitIsSend(Send node) { |
2768 visit(node.receiver); | 2768 visit(node.receiver); |
2769 HInstruction expression = pop(); | 2769 HInstruction expression = pop(); |
2770 bool isNot = node.isIsNotCheck; | 2770 bool isNot = node.isIsNotCheck; |
2771 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); | 2771 DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast); |
2772 type = type.unalias(compiler); | 2772 type = type.unalias(compiler); |
2773 if (type.isMalformed) { | 2773 if (type.containsAmbiguousTypes) { |
2774 String reasons = Types.fetchReasonsFromMalformedType(type); | 2774 String reasons = Types.fetchReasonsFromAmbiguousType(type); |
2775 if (compiler.enableTypeAssertions) { | 2775 if (compiler.enableTypeAssertions) { |
2776 generateMalformedSubtypeError(node, expression, type, reasons); | 2776 generateMalformedSubtypeError(node, expression, type, reasons); |
2777 } else { | 2777 } else { |
2778 generateRuntimeError(node, '$type is malformed: $reasons'); | 2778 generateRuntimeError(node, '$type is ambiguous: $reasons'); |
2779 } | 2779 } |
2780 } else { | 2780 } else { |
2781 HInstruction instruction = buildIsNode(node, type, expression); | 2781 HInstruction instruction = buildIsNode(node, type, expression); |
2782 if (isNot) { | 2782 if (isNot) { |
2783 add(instruction); | 2783 add(instruction); |
2784 instruction = new HNot(instruction); | 2784 instruction = new HNot(instruction); |
2785 } | 2785 } |
2786 push(instruction); | 2786 push(instruction); |
2787 } | 2787 } |
2788 } | 2788 } |
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3408 element: type.element); | 3408 element: type.element); |
3409 } | 3409 } |
3410 } | 3410 } |
3411 | 3411 |
3412 /** | 3412 /** |
3413 * Documentation wanted -- johnniwinther | 3413 * Documentation wanted -- johnniwinther |
3414 * | 3414 * |
3415 * Invariant: [argument] must not be malformed in checked mode. | 3415 * Invariant: [argument] must not be malformed in checked mode. |
3416 */ | 3416 */ |
3417 HInstruction analyzeTypeArgument(DartType argument) { | 3417 HInstruction analyzeTypeArgument(DartType argument) { |
3418 assert(invariant(currentElement, | 3418 if (argument.treatAsDynamic) { |
3419 !compiler.enableTypeAssertions || !argument.isMalformed, | |
3420 message: '$argument is malformed in checked mode')); | |
3421 if (argument == compiler.types.dynamicType || argument.isMalformed) { | |
3422 // Represent [dynamic] as [null]. | 3419 // Represent [dynamic] as [null]. |
3423 return graph.addConstantNull(compiler); | 3420 return graph.addConstantNull(compiler); |
3424 } | 3421 } |
3425 | 3422 |
3426 List<HInstruction> inputs = <HInstruction>[]; | 3423 List<HInstruction> inputs = <HInstruction>[]; |
3427 | 3424 |
3428 String template = rti.getTypeRepresentation(argument, (variable) { | 3425 String template = rti.getTypeRepresentation(argument, (variable) { |
3429 inputs.add(addTypeVariableReference(variable)); | 3426 inputs.add(addTypeVariableReference(variable)); |
3430 }); | 3427 }); |
3431 | 3428 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3467 pop(); | 3464 pop(); |
3468 } | 3465 } |
3469 | 3466 |
3470 /** | 3467 /** |
3471 * Documentation wanted -- johnniwinther | 3468 * Documentation wanted -- johnniwinther |
3472 * | 3469 * |
3473 * Invariant: [type] must not be malformed in checked mode. | 3470 * Invariant: [type] must not be malformed in checked mode. |
3474 */ | 3471 */ |
3475 handleNewSend(NewExpression node, InterfaceType type) { | 3472 handleNewSend(NewExpression node, InterfaceType type) { |
3476 Send send = node.send; | 3473 Send send = node.send; |
3477 assert(invariant(send, | |
3478 !compiler.enableTypeAssertions || !type.isMalformed, | |
3479 message: '$type is malformed in checked mode')); | |
3480 bool isListConstructor = false; | 3474 bool isListConstructor = false; |
3481 computeType(element) { | 3475 computeType(element) { |
3482 Element originalElement = elements[send]; | 3476 Element originalElement = elements[send]; |
3483 if (Elements.isFixedListConstructorCall(originalElement, send, compiler) | 3477 if (Elements.isFixedListConstructorCall(originalElement, send, compiler) |
3484 || Elements.isFilledListConstructorCall( | 3478 || Elements.isFilledListConstructorCall( |
3485 originalElement, send, compiler)) { | 3479 originalElement, send, compiler)) { |
3486 isListConstructor = true; | 3480 isListConstructor = true; |
3487 HType inferred = | 3481 HType inferred = |
3488 new HType.inferredForNode(currentElement, send, compiler); | 3482 new HType.inferredForNode(currentElement, send, compiler); |
3489 return inferred.isUnknown() ? backend.fixedArrayType : inferred; | 3483 return inferred.isUnknown() ? backend.fixedArrayType : inferred; |
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3781 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 3775 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
3782 stack.add(graph.addConstant(constant, compiler)); | 3776 stack.add(graph.addConstant(constant, compiler)); |
3783 if (isSymbolConstructor) { | 3777 if (isSymbolConstructor) { |
3784 ConstructedConstant symbol = constant; | 3778 ConstructedConstant symbol = constant; |
3785 StringConstant stringConstant = symbol.fields.single; | 3779 StringConstant stringConstant = symbol.fields.single; |
3786 String nameString = stringConstant.toDartString().slowToString(); | 3780 String nameString = stringConstant.toDartString().slowToString(); |
3787 compiler.enqueuer.codegen.registerConstSymbol(nameString, elements); | 3781 compiler.enqueuer.codegen.registerConstSymbol(nameString, elements); |
3788 } | 3782 } |
3789 } else { | 3783 } else { |
3790 DartType type = elements.getType(node); | 3784 DartType type = elements.getType(node); |
3791 if (compiler.enableTypeAssertions && type.isMalformed) { | 3785 if (compiler.enableTypeAssertions && type.containsAmbiguousTypes) { |
3792 String reasons = Types.fetchReasonsFromMalformedType(type); | 3786 String reasons = Types.fetchReasonsFromAmbiguousType(type); |
3793 // TODO(johnniwinther): Change to resemble type errors from bounds check | 3787 // TODO(johnniwinther): Change to resemble type errors from bounds check |
3794 // on type arguments. | 3788 // on type arguments. |
3795 generateRuntimeError(node, '$type is malformed: $reasons'); | 3789 generateRuntimeError(node, '$type is malformed: $reasons'); |
3796 } else { | 3790 } else { |
3797 // TODO(karlklose): move this type registration to the codegen. | 3791 // TODO(karlklose): move this type registration to the codegen. |
3798 compiler.codegenWorld.instantiatedTypes.add(type); | 3792 compiler.codegenWorld.instantiatedTypes.add(type); |
3799 handleNewSend(node, type); | 3793 handleNewSend(node, type); |
3800 } | 3794 } |
3801 } | 3795 } |
3802 } | 3796 } |
(...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4920 HInvokeStatic unwrappedException = pop(); | 4914 HInvokeStatic unwrappedException = pop(); |
4921 tryInstruction.exception = exception; | 4915 tryInstruction.exception = exception; |
4922 Link<Node> link = node.catchBlocks.nodes; | 4916 Link<Node> link = node.catchBlocks.nodes; |
4923 | 4917 |
4924 void pushCondition(CatchBlock catchBlock) { | 4918 void pushCondition(CatchBlock catchBlock) { |
4925 if (catchBlock.onKeyword != null) { | 4919 if (catchBlock.onKeyword != null) { |
4926 DartType type = elements.getType(catchBlock.type); | 4920 DartType type = elements.getType(catchBlock.type); |
4927 if (type == null) { | 4921 if (type == null) { |
4928 compiler.internalError('On with no type', node: catchBlock.type); | 4922 compiler.internalError('On with no type', node: catchBlock.type); |
4929 } | 4923 } |
4930 if (type.isMalformed) { | 4924 // TODO(karlkose): support type arguments here. |
4931 // TODO(johnniwinther): Handle malformed types in [HIs] instead. | 4925 HInstruction condition = new HIs(type, |
4932 HInstruction condition = | 4926 <HInstruction>[unwrappedException], |
4933 graph.addConstantBool(true, compiler); | 4927 HIs.RAW_CHECK); |
4934 stack.add(condition); | 4928 push(condition); |
4935 } else { | |
4936 // TODO(karlkose): support type arguments here. | |
4937 HInstruction condition = new HIs(type, | |
4938 <HInstruction>[unwrappedException], | |
4939 HIs.RAW_CHECK); | |
4940 push(condition); | |
4941 } | |
4942 } else { | 4929 } else { |
4943 VariableDefinitions declaration = catchBlock.formals.nodes.head; | 4930 VariableDefinitions declaration = catchBlock.formals.nodes.head; |
4944 HInstruction condition = null; | 4931 HInstruction condition = null; |
4945 if (declaration.type == null) { | 4932 if (declaration.type == null) { |
4946 condition = graph.addConstantBool(true, compiler); | 4933 condition = graph.addConstantBool(true, compiler); |
4947 stack.add(condition); | 4934 stack.add(condition); |
4948 } else { | 4935 } else { |
4949 // TODO(aprelev@gmail.com): Once old catch syntax is removed | 4936 // TODO(aprelev@gmail.com): Once old catch syntax is removed |
4950 // "if" condition above and this "else" branch should be deleted as | 4937 // "if" condition above and this "else" branch should be deleted as |
4951 // type of declared variable won't matter for the catch | 4938 // type of declared variable won't matter for the catch |
(...skipping 12 matching lines...) Expand all Loading... |
4964 | 4951 |
4965 void visitThen() { | 4952 void visitThen() { |
4966 CatchBlock catchBlock = link.head; | 4953 CatchBlock catchBlock = link.head; |
4967 link = link.tail; | 4954 link = link.tail; |
4968 | 4955 |
4969 if (compiler.enableTypeAssertions) { | 4956 if (compiler.enableTypeAssertions) { |
4970 // In checked mode: throw a type error if the on-catch type is | 4957 // In checked mode: throw a type error if the on-catch type is |
4971 // malformed. | 4958 // malformed. |
4972 if (catchBlock.onKeyword != null) { | 4959 if (catchBlock.onKeyword != null) { |
4973 DartType type = elements.getType(catchBlock.type); | 4960 DartType type = elements.getType(catchBlock.type); |
4974 if (type != null && type.isMalformed) { | 4961 if (type != null && type.containsAmbiguousTypes) { |
4975 String reasons = Types.fetchReasonsFromMalformedType(type); | 4962 String reasons = Types.fetchReasonsFromAmbiguousType(type); |
4976 generateMalformedSubtypeError(node, | 4963 generateMalformedSubtypeError(node, |
4977 unwrappedException, type, reasons); | 4964 unwrappedException, type, reasons); |
4978 pop(); | 4965 pop(); |
4979 return; | 4966 return; |
4980 } | 4967 } |
4981 } | 4968 } |
4982 } | 4969 } |
4983 if (catchBlock.exception != null) { | 4970 if (catchBlock.exception != null) { |
4984 localsHandler.updateLocal(elements[catchBlock.exception], | 4971 localsHandler.updateLocal(elements[catchBlock.exception], |
4985 unwrappedException); | 4972 unwrappedException); |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5518 new HSubGraphBlockInformation(elseBranch.graph)); | 5505 new HSubGraphBlockInformation(elseBranch.graph)); |
5519 | 5506 |
5520 HBasicBlock conditionStartBlock = conditionBranch.block; | 5507 HBasicBlock conditionStartBlock = conditionBranch.block; |
5521 conditionStartBlock.setBlockFlow(info, joinBlock); | 5508 conditionStartBlock.setBlockFlow(info, joinBlock); |
5522 SubGraph conditionGraph = conditionBranch.graph; | 5509 SubGraph conditionGraph = conditionBranch.graph; |
5523 HIf branch = conditionGraph.end.last; | 5510 HIf branch = conditionGraph.end.last; |
5524 assert(branch is HIf); | 5511 assert(branch is HIf); |
5525 branch.blockInformation = conditionStartBlock.blockFlow; | 5512 branch.blockInformation = conditionStartBlock.blockFlow; |
5526 } | 5513 } |
5527 } | 5514 } |
OLD | NEW |