Chromium Code Reviews| 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 2521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2641 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); | 2646 TypeAnnotation typeAnnotation = argument.asTypeAnnotation(); |
| 2642 bool isNot = false; | 2647 bool isNot = false; |
| 2643 // TODO(ngeoffray): Duplicating pattern in resolver. We should | 2648 // TODO(ngeoffray): Duplicating pattern in resolver. We should |
| 2644 // add a new kind of node. | 2649 // add a new kind of node. |
| 2645 if (typeAnnotation == null) { | 2650 if (typeAnnotation == null) { |
| 2646 typeAnnotation = argument.asSend().receiver; | 2651 typeAnnotation = argument.asSend().receiver; |
| 2647 isNot = true; | 2652 isNot = true; |
| 2648 } | 2653 } |
| 2649 | 2654 |
| 2650 DartType type = elements.getType(typeAnnotation); | 2655 DartType type = elements.getType(typeAnnotation); |
| 2656 if (type.isMalformed) { | |
| 2657 String reasons = fetchReasonsFromMalformedType(type); | |
| 2658 if (compiler.enableTypeAssertions) { | |
| 2659 generateMalformedSubtypeError(node, expression, type, reasons); | |
| 2660 } else { | |
| 2661 generateRuntimeError(node, '$type is malformed: $reasons'); | |
| 2662 } | |
| 2663 return; | |
| 2664 } | |
| 2651 HInstruction typeInfo = null; | 2665 HInstruction typeInfo = null; |
| 2652 if (RuntimeTypeInformation.hasTypeArguments(type)) { | 2666 if (RuntimeTypeInformation.hasTypeArguments(type)) { |
| 2653 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression); | 2667 pushInvokeHelper1(interceptors.getGetRuntimeTypeInfo(), expression); |
| 2654 typeInfo = pop(); | 2668 typeInfo = pop(); |
| 2655 } | 2669 } |
| 2656 if (type.element.isTypeVariable()) { | 2670 if (type.element.isTypeVariable()) { |
| 2657 // TODO(karlklose): We currently answer true to any is check | 2671 // TODO(karlklose): We currently answer true to any is check |
| 2658 // involving a type variable -- both is T and is !T -- until | 2672 // involving a type variable -- both is T and is !T -- until |
| 2659 // we have a proper implementation of reified generics. | 2673 // we have a proper implementation of reified generics. |
| 2660 stack.add(graph.addConstantBool(true, constantSystem)); | 2674 stack.add(graph.addConstantBool(true, constantSystem)); |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3052 } | 3066 } |
| 3053 } else { | 3067 } else { |
| 3054 target = new HInvokeSuper(inputs); | 3068 target = new HInvokeSuper(inputs); |
| 3055 add(target); | 3069 add(target); |
| 3056 inputs = <HInstruction>[target]; | 3070 inputs = <HInstruction>[target]; |
| 3057 addDynamicSendArgumentsToList(node, inputs); | 3071 addDynamicSendArgumentsToList(node, inputs); |
| 3058 push(new HInvokeClosure(selector, inputs)); | 3072 push(new HInvokeClosure(selector, inputs)); |
| 3059 } | 3073 } |
| 3060 } | 3074 } |
| 3061 | 3075 |
| 3076 /** | |
| 3077 * Documentation wanted -- johnniwinther | |
| 3078 * | |
| 3079 * Invariant: [argument] must not be malformed in checked mode. | |
| 3080 */ | |
| 3062 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { | 3081 HInstruction analyzeTypeArgument(DartType argument, Node currentNode) { |
| 3063 if (argument == compiler.types.dynamicType) { | 3082 assert(invariant(currentNode, |
| 3083 !compiler.enableTypeAssertions || !argument.isMalformed, | |
| 3084 message: '$argument is malformed in checked mode')); | |
| 3085 if (argument == compiler.types.dynamicType || argument.isMalformed) { | |
| 3064 // Represent [dynamic] as [null]. | 3086 // Represent [dynamic] as [null]. |
| 3065 return graph.addConstantNull(constantSystem); | 3087 return graph.addConstantNull(constantSystem); |
| 3066 } | 3088 } |
| 3067 | 3089 |
| 3068 // These variables are shared between invocations of the helper methods. | 3090 // These variables are shared between invocations of the helper methods. |
| 3069 HInstruction typeInfo; | 3091 HInstruction typeInfo; |
| 3070 StringBuffer template = new StringBuffer(); | 3092 StringBuffer template = new StringBuffer(); |
| 3071 List<HInstruction> inputs = <HInstruction>[]; | 3093 List<HInstruction> inputs = <HInstruction>[]; |
| 3072 | 3094 |
| 3073 /** | 3095 /** |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3181 add(typeInfo); | 3203 add(typeInfo); |
| 3182 | 3204 |
| 3183 // Set the runtime type information on the object. | 3205 // Set the runtime type information on the object. |
| 3184 Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo(); | 3206 Element typeInfoSetterElement = interceptors.getSetRuntimeTypeInfo(); |
| 3185 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); | 3207 HInstruction typeInfoSetter = new HStatic(typeInfoSetterElement); |
| 3186 add(typeInfoSetter); | 3208 add(typeInfoSetter); |
| 3187 add(new HInvokeStatic( | 3209 add(new HInvokeStatic( |
| 3188 <HInstruction>[typeInfoSetter, newObject, typeInfo])); | 3210 <HInstruction>[typeInfoSetter, newObject, typeInfo])); |
| 3189 } | 3211 } |
| 3190 | 3212 |
| 3213 /** | |
| 3214 * Documentation wanted -- johnniwinther | |
| 3215 * | |
| 3216 * Invariant: [type] must not be malformed in checked mode. | |
| 3217 */ | |
| 3191 visitNewSend(Send node, InterfaceType type) { | 3218 visitNewSend(Send node, InterfaceType type) { |
| 3219 assert(invariant(node, | |
| 3220 !compiler.enableTypeAssertions || !type.isMalformed, | |
| 3221 message: '$type is malformed in checked mode')); | |
| 3192 bool isListConstructor = false; | 3222 bool isListConstructor = false; |
| 3193 computeType(element) { | 3223 computeType(element) { |
| 3194 Element originalElement = elements[node]; | 3224 Element originalElement = elements[node]; |
| 3195 if (identical(originalElement.getEnclosingClass(), compiler.listClass)) { | 3225 if (identical(originalElement.getEnclosingClass(), compiler.listClass)) { |
| 3196 isListConstructor = true; | 3226 isListConstructor = true; |
| 3197 if (node.arguments.isEmpty) { | 3227 if (node.arguments.isEmpty) { |
| 3198 return HType.EXTENDABLE_ARRAY; | 3228 return HType.EXTENDABLE_ARRAY; |
| 3199 } else { | 3229 } else { |
| 3200 return HType.MUTABLE_ARRAY; | 3230 return HType.MUTABLE_ARRAY; |
| 3201 } | 3231 } |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3421 FunctionSignature signature = function.computeSignature(compiler); | 3451 FunctionSignature signature = function.computeSignature(compiler); |
| 3422 signature.forEachParameter((Element parameter) { | 3452 signature.forEachParameter((Element parameter) { |
| 3423 existingArguments.add(parameter.name.slowToString()); | 3453 existingArguments.add(parameter.name.slowToString()); |
| 3424 }); | 3454 }); |
| 3425 generateThrowNoSuchMethod(diagnosticNode, | 3455 generateThrowNoSuchMethod(diagnosticNode, |
| 3426 function.name.slowToString(), | 3456 function.name.slowToString(), |
| 3427 argumentNodes: argumentNodes, | 3457 argumentNodes: argumentNodes, |
| 3428 existingArguments: existingArguments); | 3458 existingArguments: existingArguments); |
| 3429 } | 3459 } |
| 3430 | 3460 |
| 3461 void generateMalformedSubtypeError(Node node, HInstruction value, | |
| 3462 DartType type, String reasons) { | |
| 3463 HInstruction typeString = addConstantString(node, type.toString()); | |
| 3464 HInstruction reasonsString = addConstantString(node, reasons); | |
| 3465 Element helper = interceptors.getThrowMalformedSubtypeError(); | |
| 3466 pushInvokeHelper3(helper, value, typeString, reasonsString); | |
| 3467 } | |
| 3468 | |
| 3431 visitNewExpression(NewExpression node) { | 3469 visitNewExpression(NewExpression node) { |
| 3432 Element element = elements[node.send]; | 3470 Element element = elements[node.send]; |
| 3433 if (!Elements.isErroneousElement(element) && | 3471 if (!Elements.isErroneousElement(element)) { |
| 3434 !Elements.isMalformedElement(element)) { | |
| 3435 FunctionElement function = element; | 3472 FunctionElement function = element; |
| 3436 element = function.redirectionTarget; | 3473 element = function.redirectionTarget; |
| 3437 } | 3474 } |
| 3438 if (Elements.isErroneousElement(element)) { | 3475 if (Elements.isErroneousElement(element)) { |
| 3439 ErroneousElement error = element; | 3476 ErroneousElement error = element; |
| 3440 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { | 3477 if (error.messageKind == MessageKind.CANNOT_FIND_CONSTRUCTOR) { |
| 3441 generateThrowNoSuchMethod(node.send, | 3478 generateThrowNoSuchMethod(node.send, |
| 3442 getTargetName(error, 'constructor'), | 3479 getTargetName(error, 'constructor'), |
| 3443 argumentNodes: node.send.arguments); | 3480 argumentNodes: node.send.arguments); |
| 3444 } else if (error.messageKind == MessageKind.CANNOT_RESOLVE) { | 3481 } else { |
| 3445 Message message = error.messageKind.message(error.messageArguments); | 3482 Message message = error.messageKind.message(error.messageArguments); |
| 3446 generateRuntimeError(node.send, message.toString()); | 3483 generateRuntimeError(node.send, message.toString()); |
| 3447 } else { | |
| 3448 compiler.internalError('unexpected unresolved constructor call', | |
| 3449 node: node); | |
| 3450 } | 3484 } |
| 3451 } else if (node.isConst()) { | 3485 } else if (node.isConst()) { |
| 3452 // TODO(karlklose): add type representation | 3486 // TODO(karlklose): add type representation |
| 3453 ConstantHandler handler = compiler.constantHandler; | 3487 ConstantHandler handler = compiler.constantHandler; |
| 3454 Constant constant = handler.compileNodeWithDefinitions(node, elements); | 3488 Constant constant = handler.compileNodeWithDefinitions(node, elements); |
| 3455 stack.add(graph.addConstant(constant)); | 3489 stack.add(graph.addConstant(constant)); |
| 3456 } else if (Elements.isMalformedElement(element)) { | |
| 3457 Message message = | |
| 3458 MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER.message([element]); | |
| 3459 generateRuntimeError(node.send, message.toString()); | |
| 3460 } else { | 3490 } else { |
| 3461 visitNewSend(node.send, elements.getType(node)); | 3491 DartType type = elements.getType(node); |
| 3492 if (compiler.enableTypeAssertions && type.isMalformed) { | |
| 3493 ErroneousElement error; | |
| 3494 type.forEachMalformedType((MalformedType malformedType) { | |
| 3495 error = malformedType.element; | |
| 3496 return false; // Visit the for malformed type only. | |
|
ahe
2012/11/30 15:44:07
I'm not sure I understand this comment.
Johnni Winther
2012/12/04 10:07:17
Changed to include all errors.
| |
| 3497 }); | |
| 3498 Message message = error.messageKind.message(error.messageArguments); | |
| 3499 generateRuntimeError(node, message.toString()); | |
| 3500 } else { | |
| 3501 visitNewSend(node.send, type); | |
| 3502 } | |
| 3462 } | 3503 } |
| 3463 } | 3504 } |
| 3464 | 3505 |
| 3465 visitSendSet(SendSet node) { | 3506 visitSendSet(SendSet node) { |
| 3466 Element element = elements[node]; | 3507 Element element = elements[node]; |
| 3467 if (!Elements.isUnresolved(element) && element.impliesType()) { | 3508 if (!Elements.isUnresolved(element) && element.impliesType()) { |
| 3468 Identifier selector = node.selector; | 3509 Identifier selector = node.selector; |
| 3469 generateThrowNoSuchMethod(node, selector.source.slowToString(), | 3510 generateThrowNoSuchMethod(node, selector.source.slowToString(), |
| 3470 argumentNodes: node.arguments); | 3511 argumentNodes: node.arguments); |
| 3471 return; | 3512 return; |
| (...skipping 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4902 new HSubGraphBlockInformation(elseBranch.graph)); | 4943 new HSubGraphBlockInformation(elseBranch.graph)); |
| 4903 | 4944 |
| 4904 HBasicBlock conditionStartBlock = conditionBranch.block; | 4945 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 4905 conditionStartBlock.setBlockFlow(info, joinBlock); | 4946 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 4906 SubGraph conditionGraph = conditionBranch.graph; | 4947 SubGraph conditionGraph = conditionBranch.graph; |
| 4907 HIf branch = conditionGraph.end.last; | 4948 HIf branch = conditionGraph.end.last; |
| 4908 assert(branch is HIf); | 4949 assert(branch is HIf); |
| 4909 branch.blockInformation = conditionStartBlock.blockFlow; | 4950 branch.blockInformation = conditionStartBlock.blockFlow; |
| 4910 } | 4951 } |
| 4911 } | 4952 } |
| OLD | NEW |