| 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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 } | 100 } |
| 101 | 101 |
| 102 Element getExceptionUnwrapper() { | 102 Element getExceptionUnwrapper() { |
| 103 return compiler.findHelper(const SourceString('unwrapException')); | 103 return compiler.findHelper(const SourceString('unwrapException')); |
| 104 } | 104 } |
| 105 | 105 |
| 106 Element getThrowRuntimeError() { | 106 Element getThrowRuntimeError() { |
| 107 return compiler.findHelper(const SourceString('throwRuntimeError')); | 107 return compiler.findHelper(const SourceString('throwRuntimeError')); |
| 108 } | 108 } |
| 109 | 109 |
| 110 Element getThrowMalformedSubtypeError() { |
| 111 return compiler.findHelper( |
| 112 const SourceString('throwMalformedSubtypeError')); |
| 113 } |
| 114 |
| 110 Element getThrowAbstractClassInstantiationError() { | 115 Element getThrowAbstractClassInstantiationError() { |
| 111 return compiler.findHelper( | 116 return compiler.findHelper( |
| 112 const SourceString('throwAbstractClassInstantiationError')); | 117 const SourceString('throwAbstractClassInstantiationError')); |
| 113 } | 118 } |
| 114 | 119 |
| 115 Element getClosureConverter() { | 120 Element getClosureConverter() { |
| 116 return compiler.findHelper(const SourceString('convertDartClosureToJS')); | 121 return compiler.findHelper(const SourceString('convertDartClosureToJS')); |
| 117 } | 122 } |
| 118 | 123 |
| 119 Element getTraceFromException() { | 124 Element getTraceFromException() { |
| (...skipping 2538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2658 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); | 2663 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); |
| 2659 bool isNot = false; | 2664 bool isNot = false; |
| 2660 // TODO(ngeoffray): Duplicating pattern in resolver. We should | 2665 // TODO(ngeoffray): Duplicating pattern in resolver. We should |
| 2661 // add a new kind of node. | 2666 // add a new kind of node. |
| 2662 if (typeAnnotation == null) { | 2667 if (typeAnnotation == null) { |
| 2663 typeAnnotation = argument.asSend().receiver; | 2668 typeAnnotation = argument.asSend().receiver; |
| 2664 isNot = true; | 2669 isNot = true; |
| 2665 } | 2670 } |
| 2666 | 2671 |
| 2667 DartType type = elements.getType(typeAnnotation); | 2672 DartType type = elements.getType(typeAnnotation); |
| 2673 if (type.isMalformed) { |
| 2674 String reasons = fetchReasonsFromMalformedType(type); |
| 2675 if (compiler.enableTypeAssertions) { |
| 2676 generateMalformedSubtypeError(node, expression, type, reasons); |
| 2677 } else { |
| 2678 generateRuntimeError(node, '$type is malformed: $reasons'); |
| 2679 } |
| 2680 return; |
| 2681 } |
| 2668 HInstruction typeInfo = null; | 2682 HInstruction typeInfo = null; |
| 2669 if (RuntimeTypeInformation.hasTypeArguments(type)) { | 2683 if (RuntimeTypeInformation.hasTypeArguments(type)) { |
| 2670 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression); | 2684 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression); |
| 2671 typeInfo = pop(); | 2685 typeInfo = pop(); |
| 2672 } | 2686 } |
| 2673 if (type.element.isTypeVariable()) { | 2687 if (type.element.isTypeVariable()) { |
| 2674 // TODO(karlklose): We currently answer true to any is check | 2688 // TODO(karlklose): We currently answer true to any is check |
| 2675 // involving a type variable -- both is T and is !T -- until | 2689 // involving a type variable -- both is T and is !T -- until |
| 2676 // we have a proper implementation of reified generics. | 2690 // we have a proper implementation of reified generics. |
| 2677 stack.add(graph.addConstantBool(true, constantSystem)); | 2691 stack.add(graph.addConstantBool(true, constantSystem)); |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3069 } | 3083 } |
| 3070 } else { | 3084 } else { |
| 3071 target = new HInvokeSuper(inputs); | 3085 target = new HInvokeSuper(inputs); |
| 3072 add(target); | 3086 add(target); |
| 3073 inputs = <HInstruction>[target]; | 3087 inputs = <HInstruction>[target]; |
| 3074 addDynamicSendArgumentsToList(node, inputs); | 3088 addDynamicSendArgumentsToList(node, inputs); |
| 3075 push(new HInvokeClosure(selector, inputs)); | 3089 push(new HInvokeClosure(selector, inputs)); |
| 3076 } | 3090 } |
| 3077 } | 3091 } |
| 3078 | 3092 |
| 3093 /** |
| 3094 * Documentation wanted -- johnniwinther |
| 3095 * |
| 3096 * Invariant: [argument] must not be malformed in checked mode. |
| 3097 */ |
| 3079 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { | 3098 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { |
| 3080 if (argument == compiler.types.dynamicType) { | 3099 assert(invariant(currentNode, |
| 3100 !compiler.enableTypeAssertions || !argument.isMalformed, |
| 3101 message: '$argument is malformed in checked mode')); |
| 3102 if (argument == compiler.types.dynamicType || argument.isMalformed) { |
| 3081 // Represent [dynamic] as [null]. | 3103 // Represent [dynamic] as [null]. |
| 3082 return graph.addConstantNull(constantSystem); | 3104 return graph.addConstantNull(constantSystem); |
| 3083 } | 3105 } |
| 3084 | 3106 |
| 3085 // These variables are shared between invocations of the helper methods. | 3107 // These variables are shared between invocations of the helper methods. |
| 3086 HInstruction typeInfo; | 3108 HInstruction typeInfo; |
| 3087 StringBuffer template = new StringBuffer(); | 3109 StringBuffer template = new StringBuffer(); |
| 3088 List<HInstruction> inputs = <HInstruction>[]; | 3110 List<HInstruction> inputs = <HInstruction>[]; |
| 3089 | 3111 |
| 3090 /** | 3112 /** |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3198 add(typeInfo); | 3220 add(typeInfo); |
| 3199 | 3221 |
| 3200 // Set the runtime type information on the object. | 3222 // Set the runtime type information on the object. |
| 3201 Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo(); | 3223 Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo(); |
| 3202 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); | 3224 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); |
| 3203 add(typeInfoSetter); | 3225 add(typeInfoSetter); |
| 3204 add(new HInvokeStatic( | 3226 add(new HInvokeStatic( |
| 3205 <HInstruction>[typeInfoSetter, newObject, typeInfo])); | 3227 <HInstruction>[typeInfoSetter, newObject, typeInfo])); |
| 3206 } | 3228 } |
| 3207 | 3229 |
| 3230 /** |
| 3231 * Documentation wanted -- johnniwinther |
| 3232 * |
| 3233 * Invariant: [type] must not be malformed in checked mode. |
| 3234 */ |
| 3208 visitNewSend(Send node, InterfaceType type) { | 3235 visitNewSend(Send node, InterfaceType type) { |
| 3236 assert(invariant(node, |
| 3237 !compiler.enableTypeAssertions || !type.isMalformed, |
| 3238 message: '$type is malformed in checked mode')); |
| 3209 bool isListConstructor = false; | 3239 bool isListConstructor = false; |
| 3210 computeType(element) { | 3240 computeType(element) { |
| 3211 Element originalElement = elements[node]; | 3241 Element originalElement = elements[node]; |
| 3212 if (identical(originalElement.getEnclosingClass(), compiler.listClass)) { | 3242 if (identical(originalElement.getEnclosingClass(), compiler.listClass)) { |
| 3213 isListConstructor = true; | 3243 isListConstructor = true; |
| 3214 if (node.arguments.isEmpty) { | 3244 if (node.arguments.isEmpty) { |
| 3215 return HType.EXTENDABLE_ARRAY; | 3245 return HType.EXTENDABLE_ARRAY; |
| 3216 } else { | 3246 } else { |
| 3217 return HType.MUTABLE_ARRAY; | 3247 return HType.MUTABLE_ARRAY; |
| 3218 } | 3248 } |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3438 FunctionSignature signature = function.computeSignature(compiler); | 3468 FunctionSignature signature = function.computeSignature(compiler); |
| 3439 signature.forEachParameter((Element parameter) { | 3469 signature.forEachParameter((Element parameter) { |
| 3440 existingArguments.add(parameter.name.slowToString()); | 3470 existingArguments.add(parameter.name.slowToString()); |
| 3441 }); | 3471 }); |
| 3442 generateThrowNoSuchMethod(diagnosticNode, | 3472 generateThrowNoSuchMethod(diagnosticNode, |
| 3443 function.name.slowToString(), | 3473 function.name.slowToString(), |
| 3444 argumentNodes: argumentNodes, | 3474 argumentNodes: argumentNodes, |
| 3445 existingArguments: existingArguments); | 3475 existingArguments: existingArguments); |
| 3446 } | 3476 } |
| 3447 | 3477 |
| 3478 void generateMalformedSubtypeError(Node node, HInstruction value, |
| 3479 DartType type, String reasons) { |
| 3480 HInstruction typeString = addConstantString(node, type.toString()); |
| 3481 HInstruction reasonsString = addConstantString(node, reasons); |
| 3482 Element helper = interceptors.getThrowMalformedSubtypeError(); |
| 3483 pushInvokeHelper3(helper, value, typeString, reasonsString); |
| 3484 } |
| 3485 |
| 3448 visitNewExpression(NewExpression node) { | 3486 visitNewExpression(NewExpression node) { |
| 3449 Element element = elements[node.send]; | 3487 Element element = elements[node.send]; |
| 3450 if (!Elements.isUnresolved(element)) { | 3488 if (!Elements.isErroneousElement(element)) { |
| 3451 FunctionElement function = element; | 3489 FunctionElement function = element; |
| 3452 element = function.redirectionTarget; | 3490 element = function.redirectionTarget; |
| 3453 } | 3491 } |
| 3454 if (Elements.isErroneousElement(element)) { | 3492 if (Elements.isErroneousElement(element)) { |
| 3455 ErroneousElement error = element; | 3493 ErroneousElement error = element; |
| 3456 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { | 3494 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
| 3457 generateThrowNoSuchMethod(node.send, | 3495 generateThrowNoSuchMethod(node.send, |
| 3458 getTargetName(error, 'constructor'), | 3496 getTargetName(error, 'constructor'), |
| 3459 argumentNodes: node.send.arguments); | 3497 argumentNodes: node.send.arguments); |
| 3460 } else if (error.messageKind == MessageKind.CANNOT_RESOLVE) { | 3498 } else { |
| 3461 Message message = error.messageKind.message(error.messageArguments); | 3499 Message message = error.messageKind.message(error.messageArguments); |
| 3462 generateRuntimeError(node.send, message.toString()); | 3500 generateRuntimeError(node.send, message.toString()); |
| 3463 } else { | |
| 3464 compiler.internalError('unexpected unresolved constructor call', | |
| 3465 node: node); | |
| 3466 } | 3501 } |
| 3467 } else if (node.isConst()) { | 3502 } else if (node.isConst()) { |
| 3468 // TODO(karlklose): add type representation | 3503 // TODO(karlklose): add type representation |
| 3469 ConstantHandler handler = compiler.constantHandler; | 3504 ConstantHandler handler = compiler.constantHandler; |
| 3470 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 3505 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| 3471 stack.add(graph.addConstant(constant)); | 3506 stack.add(graph.addConstant(constant)); |
| 3472 } else { | 3507 } else { |
| 3473 DartType dartType = elements.getType(node); | 3508 DartType type = elements.getType(node); |
| 3474 if (dartType.kind == TypeKind.MALFORMED_TYPE && | 3509 if (compiler.enableTypeAssertions && type.isMalformed) { |
| 3475 compiler.enableTypeAssertions) { | 3510 String reasons = fetchReasonsFromMalformedType(type); |
| 3476 Message message = MessageKind.MALFORMED_TYPE_REFERENCE.message([node]); | 3511 // TODO(johnniwinther): Change to resemble type errors from bounds check |
| 3477 generateRuntimeError(node.send, message.toString()); | 3512 // on type arguments. |
| 3513 generateRuntimeError(node, '$type is malformed: $reasons'); |
| 3478 } else { | 3514 } else { |
| 3479 visitNewSend(node.send, dartType); | 3515 visitNewSend(node.send, type); |
| 3480 } | 3516 } |
| 3481 } | 3517 } |
| 3482 } | 3518 } |
| 3483 | 3519 |
| 3484 visitSendSet(SendSet node) { | 3520 visitSendSet(SendSet node) { |
| 3485 Element element = elements[node]; | 3521 Element element = elements[node]; |
| 3486 if (!Elements.isUnresolved(element) && element.impliesType()) { | 3522 if (!Elements.isUnresolved(element) && element.impliesType()) { |
| 3487 Identifier selector = node.selector; | 3523 Identifier selector = node.selector; |
| 3488 generateThrowNoSuchMethod(node, selector.source.slowToString(), | 3524 generateThrowNoSuchMethod(node, selector.source.slowToString(), |
| 3489 argumentNodes: node.arguments); | 3525 argumentNodes: node.arguments); |
| (...skipping 1431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4921 new HSubGraphBlockInformation(elseBranch.graph)); | 4957 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4922 | 4958 |
| 4923 HBasicBlock conditionStartBlock = conditionBranch.block; | 4959 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4924 conditionStartBlock.setBlockFlow(info, joinBlock); | 4960 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4925 SubGraph conditionGraph = conditionBranch.graph; | 4961 SubGraph conditionGraph = conditionBranch.graph; |
| 4926 HIf branch = conditionGraph.end.last; | 4962 HIf branch = conditionGraph.end.last; |
| 4927 assert(branch is HIf); | 4963 assert(branch is HIf); |
| 4928 branch.blockInformation = conditionStartBlock.blockFlow; | 4964 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4929 } | 4965 } |
| 4930 } | 4966 } |
| OLD | NEW |