| 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 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 parameterElement)) { | 289 parameterElement)) { |
| 290 // The parameter will be a field in the box passed as the | 290 // The parameter will be a field in the box passed as the |
| 291 // last parameter. So no need to have it. | 291 // last parameter. So no need to have it. |
| 292 return; | 292 return; |
| 293 } | 293 } |
| 294 } | 294 } |
| 295 HInstruction parameter = builder.addParameter(parameterElement); | 295 HInstruction parameter = builder.addParameter(parameterElement); |
| 296 builder.parameters[parameterElement] = parameter; | 296 builder.parameters[parameterElement] = parameter; |
| 297 directLocals[parameterElement] = parameter; | 297 directLocals[parameterElement] = parameter; |
| 298 parameter.guaranteedType = | 298 parameter.guaranteedType = |
| 299 builder.mapInferredType( | 299 builder.getGuaranteedTypeOfElement(parameterElement); |
| 300 typesTask.getGuaranteedTypeOfElement(parameterElement)); | |
| 301 }); | 300 }); |
| 302 } | 301 } |
| 303 | 302 |
| 304 enterScope(node, element); | 303 enterScope(node, element); |
| 305 | 304 |
| 306 // If the freeVariableMapping is not empty, then this function was a | 305 // If the freeVariableMapping is not empty, then this function was a |
| 307 // nested closure that captures variables. Redirect the captured | 306 // nested closure that captures variables. Redirect the captured |
| 308 // variables to fields in the closure. | 307 // variables to fields in the closure. |
| 309 closureData.freeVariableMapping.forEach((Element from, Element to) { | 308 closureData.freeVariableMapping.forEach((Element from, Element to) { |
| 310 redirectElement(from, to); | 309 redirectElement(from, to); |
| (...skipping 3058 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3369 generateWrongArgumentCountError(node, element, node.arguments); | 3368 generateWrongArgumentCountError(node, element, node.arguments); |
| 3370 return; | 3369 return; |
| 3371 } | 3370 } |
| 3372 | 3371 |
| 3373 if (isIdenticalFunction) { | 3372 if (isIdenticalFunction) { |
| 3374 pushWithPosition(new HIdentity(inputs[1], inputs[2]), node); | 3373 pushWithPosition(new HIdentity(inputs[1], inputs[2]), node); |
| 3375 return; | 3374 return; |
| 3376 } | 3375 } |
| 3377 | 3376 |
| 3378 HInvokeStatic instruction = new HInvokeStatic(inputs, HType.UNKNOWN); | 3377 HInvokeStatic instruction = new HInvokeStatic(inputs, HType.UNKNOWN); |
| 3379 // TODO(ngeoffray): Only do this if knowing the return type is | 3378 HType returnType = getGuaranteedTypeOfElement(element); |
| 3380 // useful. | 3379 if (returnType.isUnknown()) { |
| 3381 HType returnType = | 3380 // TODO(ngeoffray): Only do this if knowing the return type is |
| 3382 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( | 3381 // useful. |
| 3383 currentElement, element); | 3382 returnType = |
| 3383 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( |
| 3384 currentElement, element); |
| 3385 } |
| 3384 if (returnType != null) instruction.guaranteedType = returnType; | 3386 if (returnType != null) instruction.guaranteedType = returnType; |
| 3385 pushWithPosition(instruction, node); | 3387 pushWithPosition(instruction, node); |
| 3386 } else { | 3388 } else { |
| 3387 generateGetter(node, element); | 3389 generateGetter(node, element); |
| 3388 List<HInstruction> inputs = <HInstruction>[pop()]; | 3390 List<HInstruction> inputs = <HInstruction>[pop()]; |
| 3389 addDynamicSendArgumentsToList(node, inputs); | 3391 addDynamicSendArgumentsToList(node, inputs); |
| 3390 Selector closureSelector = new Selector.callClosureFrom(selector); | 3392 Selector closureSelector = new Selector.callClosureFrom(selector); |
| 3391 pushWithPosition(new HInvokeClosure(closureSelector, inputs), node); | 3393 pushWithPosition(new HInvokeClosure(closureSelector, inputs), node); |
| 3392 } | 3394 } |
| 3393 } | 3395 } |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3565 List<HInstruction> arguments) { | 3567 List<HInstruction> arguments) { |
| 3566 Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector); | 3568 Set<ClassElement> interceptedClasses = getInterceptedClassesOn(selector); |
| 3567 List<HInstruction> inputs = <HInstruction>[]; | 3569 List<HInstruction> inputs = <HInstruction>[]; |
| 3568 bool isIntercepted = interceptedClasses != null; | 3570 bool isIntercepted = interceptedClasses != null; |
| 3569 if (isIntercepted) { | 3571 if (isIntercepted) { |
| 3570 assert(!interceptedClasses.isEmpty); | 3572 assert(!interceptedClasses.isEmpty); |
| 3571 inputs.add(invokeInterceptor(interceptedClasses, receiver, node)); | 3573 inputs.add(invokeInterceptor(interceptedClasses, receiver, node)); |
| 3572 } | 3574 } |
| 3573 inputs.add(receiver); | 3575 inputs.add(receiver); |
| 3574 inputs.addAll(arguments); | 3576 inputs.addAll(arguments); |
| 3575 return new HInvokeDynamicMethod(selector, inputs, isIntercepted); | 3577 HInstruction invoke = new HInvokeDynamicMethod( |
| 3578 selector, inputs, isIntercepted); |
| 3579 HType returnType = mapInferredType( |
| 3580 compiler.typesTask.getGuaranteedTypeOfNode(work.element, node)); |
| 3581 if (returnType != null) { |
| 3582 invoke.guaranteedType = returnType; |
| 3583 } |
| 3584 return invoke; |
| 3576 } | 3585 } |
| 3577 | 3586 |
| 3578 visitSendSet(SendSet node) { | 3587 visitSendSet(SendSet node) { |
| 3579 Element element = elements[node]; | 3588 Element element = elements[node]; |
| 3580 if (!Elements.isUnresolved(element) && element.impliesType()) { | 3589 if (!Elements.isUnresolved(element) && element.impliesType()) { |
| 3581 Identifier selector = node.selector; | 3590 Identifier selector = node.selector; |
| 3582 generateThrowNoSuchMethod(node, selector.source.slowToString(), | 3591 generateThrowNoSuchMethod(node, selector.source.slowToString(), |
| 3583 argumentNodes: node.arguments); | 3592 argumentNodes: node.arguments); |
| 3584 return; | 3593 return; |
| 3585 } | 3594 } |
| (...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4649 cls.computeType(compiler), compiler); | 4658 cls.computeType(compiler), compiler); |
| 4650 } | 4659 } |
| 4651 } | 4660 } |
| 4652 | 4661 |
| 4653 HType mapInferredType(ConcreteType concreteType) { | 4662 HType mapInferredType(ConcreteType concreteType) { |
| 4654 if (concreteType == null) return HType.UNKNOWN; | 4663 if (concreteType == null) return HType.UNKNOWN; |
| 4655 HType ssaType = HType.CONFLICTING; | 4664 HType ssaType = HType.CONFLICTING; |
| 4656 for (BaseType baseType in concreteType.baseTypes) { | 4665 for (BaseType baseType in concreteType.baseTypes) { |
| 4657 ssaType = ssaType.union(mapBaseType(baseType), compiler); | 4666 ssaType = ssaType.union(mapBaseType(baseType), compiler); |
| 4658 } | 4667 } |
| 4659 assert(!ssaType.isConflicting()); | 4668 if (ssaType.isConflicting()) return HType.UNKNOWN; |
| 4660 return ssaType; | 4669 return ssaType; |
| 4661 } | 4670 } |
| 4662 | 4671 |
| 4672 HType getGuaranteedTypeOfElement(Element element) { |
| 4673 return mapInferredType( |
| 4674 compiler.typesTask.getGuaranteedTypeOfElement(element)); |
| 4675 } |
| 4676 |
| 4663 // [type] is either an instance of [DartType] or special objects | 4677 // [type] is either an instance of [DartType] or special objects |
| 4664 // like [native.SpecialType.JsObject], or [native.SpecialType.JsArray]. | 4678 // like [native.SpecialType.JsObject], or [native.SpecialType.JsArray]. |
| 4665 HType mapNativeType(type) { | 4679 HType mapNativeType(type) { |
| 4666 if (type == native.SpecialType.JsObject) { | 4680 if (type == native.SpecialType.JsObject) { |
| 4667 return new HType.nonNullExactClass( | 4681 return new HType.nonNullExactClass( |
| 4668 compiler.objectClass.computeType(compiler), compiler); | 4682 compiler.objectClass.computeType(compiler), compiler); |
| 4669 } else if (type == native.SpecialType.JsArray) { | 4683 } else if (type == native.SpecialType.JsArray) { |
| 4670 return HType.READABLE_ARRAY; | 4684 return HType.READABLE_ARRAY; |
| 4671 } else { | 4685 } else { |
| 4672 return new HType.nonNullSubclass(type, compiler); | 4686 return new HType.nonNullSubclass(type, compiler); |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5062 new HSubGraphBlockInformation(elseBranch.graph)); | 5076 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5063 | 5077 |
| 5064 HBasicBlock conditionStartBlock = conditionBranch.block; | 5078 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5065 conditionStartBlock.setBlockFlow(info, joinBlock); | 5079 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5066 SubGraph conditionGraph = conditionBranch.graph; | 5080 SubGraph conditionGraph = conditionBranch.graph; |
| 5067 HIf branch = conditionGraph.end.last; | 5081 HIf branch = conditionGraph.end.last; |
| 5068 assert(branch is HIf); | 5082 assert(branch is HIf); |
| 5069 branch.blockInformation = conditionStartBlock.blockFlow; | 5083 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5070 } | 5084 } |
| 5071 } | 5085 } |
| OLD | NEW |