| 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 |