| 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 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 parameterElement)) { | 287 parameterElement)) { |
| 288 // The parameter will be a field in the box passed as the | 288 // The parameter will be a field in the box passed as the |
| 289 // last parameter. So no need to have it. | 289 // last parameter. So no need to have it. |
| 290 return; | 290 return; |
| 291 } | 291 } |
| 292 } | 292 } |
| 293 HInstruction parameter = builder.addParameter(parameterElement); | 293 HInstruction parameter = builder.addParameter(parameterElement); |
| 294 builder.parameters[parameterElement] = parameter; | 294 builder.parameters[parameterElement] = parameter; |
| 295 directLocals[parameterElement] = parameter; | 295 directLocals[parameterElement] = parameter; |
| 296 parameter.instructionType = | 296 parameter.instructionType = |
| 297 builder.getGuaranteedTypeOfElement(parameterElement); | 297 new HType.inferredForElement(parameterElement, compiler); |
| 298 }); | 298 }); |
| 299 } | 299 } |
| 300 | 300 |
| 301 enterScope(node, element); | 301 enterScope(node, element); |
| 302 | 302 |
| 303 // If the freeVariableMapping is not empty, then this function was a | 303 // If the freeVariableMapping is not empty, then this function was a |
| 304 // nested closure that captures variables. Redirect the captured | 304 // nested closure that captures variables. Redirect the captured |
| 305 // variables to fields in the closure. | 305 // variables to fields in the closure. |
| 306 closureData.freeVariableMapping.forEach((Element from, Element to) { | 306 closureData.freeVariableMapping.forEach((Element from, Element to) { |
| 307 redirectElement(from, to); | 307 redirectElement(from, to); |
| (...skipping 2572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2880 compiler.cancel('At least two arguments expected', | 2880 compiler.cancel('At least two arguments expected', |
| 2881 node: node.argumentsNode); | 2881 node: node.argumentsNode); |
| 2882 } | 2882 } |
| 2883 List<HInstruction> inputs = <HInstruction>[]; | 2883 List<HInstruction> inputs = <HInstruction>[]; |
| 2884 Node type = link.head; | 2884 Node type = link.head; |
| 2885 Node code = link.tail.head; | 2885 Node code = link.tail.head; |
| 2886 addGenericSendArgumentsToList(link.tail.tail, inputs); | 2886 addGenericSendArgumentsToList(link.tail.tail, inputs); |
| 2887 | 2887 |
| 2888 native.NativeBehavior nativeBehavior = | 2888 native.NativeBehavior nativeBehavior = |
| 2889 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); | 2889 compiler.enqueuer.resolution.nativeEnqueuer.getNativeBehaviorOf(node); |
| 2890 HType ssaType = mapNativeBehaviorType(nativeBehavior); | 2890 HType ssaType = new HType.fromNativeBehavior(nativeBehavior, compiler); |
| 2891 if (code is StringNode) { | 2891 if (code is StringNode) { |
| 2892 StringNode codeString = code; | 2892 StringNode codeString = code; |
| 2893 if (!codeString.isInterpolation) { | 2893 if (!codeString.isInterpolation) { |
| 2894 // codeString may not be an interpolation, but may be a juxtaposition. | 2894 // codeString may not be an interpolation, but may be a juxtaposition. |
| 2895 push(new HForeign(codeString.dartString, ssaType, inputs)); | 2895 push(new HForeign(codeString.dartString, ssaType, inputs)); |
| 2896 return; | 2896 return; |
| 2897 } | 2897 } |
| 2898 } | 2898 } |
| 2899 compiler.cancel('JS code must be a string literal', node: code); | 2899 compiler.cancel('JS code must be a string literal', node: code); |
| 2900 } | 2900 } |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3367 generateWrongArgumentCountError(node, element, node.arguments); | 3367 generateWrongArgumentCountError(node, element, node.arguments); |
| 3368 return; | 3368 return; |
| 3369 } | 3369 } |
| 3370 | 3370 |
| 3371 if (isIdenticalFunction) { | 3371 if (isIdenticalFunction) { |
| 3372 pushWithPosition(new HIdentity(inputs[1], inputs[2]), node); | 3372 pushWithPosition(new HIdentity(inputs[1], inputs[2]), node); |
| 3373 return; | 3373 return; |
| 3374 } | 3374 } |
| 3375 | 3375 |
| 3376 HInvokeStatic instruction = new HInvokeStatic(inputs, HType.UNKNOWN); | 3376 HInvokeStatic instruction = new HInvokeStatic(inputs, HType.UNKNOWN); |
| 3377 HType returnType = getGuaranteedTypeOfElement(element); | 3377 HType returnType = new HType.inferredForElement(element, compiler); |
| 3378 if (returnType.isUnknown()) { | 3378 if (returnType.isUnknown()) { |
| 3379 // TODO(ngeoffray): Only do this if knowing the return type is | 3379 // TODO(ngeoffray): Only do this if knowing the return type is |
| 3380 // useful. | 3380 // useful. |
| 3381 returnType = | 3381 returnType = |
| 3382 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( | 3382 builder.backend.optimisticReturnTypesWithRecompilationOnTypeChange( |
| 3383 currentElement, element); | 3383 currentElement, element); |
| 3384 } | 3384 } |
| 3385 if (returnType != null) instruction.instructionType = returnType; | 3385 if (returnType != null) instruction.instructionType = returnType; |
| 3386 pushWithPosition(instruction, node); | 3386 pushWithPosition(instruction, node); |
| 3387 } else { | 3387 } else { |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3567 List<HInstruction> inputs = <HInstruction>[]; | 3567 List<HInstruction> inputs = <HInstruction>[]; |
| 3568 bool isIntercepted = interceptedClasses != null; | 3568 bool isIntercepted = interceptedClasses != null; |
| 3569 if (isIntercepted) { | 3569 if (isIntercepted) { |
| 3570 assert(!interceptedClasses.isEmpty); | 3570 assert(!interceptedClasses.isEmpty); |
| 3571 inputs.add(invokeInterceptor(interceptedClasses, receiver, node)); | 3571 inputs.add(invokeInterceptor(interceptedClasses, receiver, node)); |
| 3572 } | 3572 } |
| 3573 inputs.add(receiver); | 3573 inputs.add(receiver); |
| 3574 inputs.addAll(arguments); | 3574 inputs.addAll(arguments); |
| 3575 HInstruction invoke = new HInvokeDynamicMethod( | 3575 HInstruction invoke = new HInvokeDynamicMethod( |
| 3576 selector, inputs, isIntercepted); | 3576 selector, inputs, isIntercepted); |
| 3577 HType returnType = mapInferredType( | 3577 HType returnType = |
| 3578 compiler.typesTask.getGuaranteedTypeOfNode(currentElement, node)); | 3578 new HType.inferredForNode(currentElement, node, compiler); |
| 3579 |
| 3579 if (returnType != null) { | 3580 if (returnType != null) { |
| 3580 invoke.instructionType = returnType; | 3581 invoke.instructionType = returnType; |
| 3581 } | 3582 } |
| 3582 return invoke; | 3583 return invoke; |
| 3583 } | 3584 } |
| 3584 | 3585 |
| 3585 visitSendSet(SendSet node) { | 3586 visitSendSet(SendSet node) { |
| 3586 Element element = elements[node]; | 3587 Element element = elements[node]; |
| 3587 if (!Elements.isUnresolved(element) && element.impliesType()) { | 3588 if (!Elements.isUnresolved(element) && element.impliesType()) { |
| 3588 Identifier selector = node.selector; | 3589 Identifier selector = node.selector; |
| (...skipping 1059 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4648 visit(node.block); | 4649 visit(node.block); |
| 4649 } | 4650 } |
| 4650 | 4651 |
| 4651 visitTypedef(Typedef node) { | 4652 visitTypedef(Typedef node) { |
| 4652 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); | 4653 compiler.unimplemented('SsaBuilder.visitTypedef', node: node); |
| 4653 } | 4654 } |
| 4654 | 4655 |
| 4655 visitTypeVariable(TypeVariable node) { | 4656 visitTypeVariable(TypeVariable node) { |
| 4656 compiler.internalError('SsaBuilder.visitTypeVariable'); | 4657 compiler.internalError('SsaBuilder.visitTypeVariable'); |
| 4657 } | 4658 } |
| 4658 | |
| 4659 HType mapBaseType(BaseType baseType) { | |
| 4660 if (!baseType.isClass()) return HType.UNKNOWN; | |
| 4661 ClassBaseType classBaseType = baseType; | |
| 4662 ClassElement cls = classBaseType.element; | |
| 4663 // Special case the list and map classes that are used as types | |
| 4664 // for literals in the type inferrer. | |
| 4665 if (cls == compiler.listClass) { | |
| 4666 return HType.READABLE_ARRAY; | |
| 4667 } else if (cls == compiler.mapClass) { | |
| 4668 // TODO(ngeoffray): get the actual implementation of a map | |
| 4669 // literal. | |
| 4670 return new HType.nonNullSubtype( | |
| 4671 compiler.mapLiteralClass.computeType(compiler), compiler); | |
| 4672 } else { | |
| 4673 return new HType.nonNullExactClass( | |
| 4674 cls.computeType(compiler), compiler); | |
| 4675 } | |
| 4676 } | |
| 4677 | |
| 4678 HType mapInferredType(ConcreteType concreteType) { | |
| 4679 if (concreteType == null) return HType.UNKNOWN; | |
| 4680 HType ssaType = HType.CONFLICTING; | |
| 4681 for (BaseType baseType in concreteType.baseTypes) { | |
| 4682 ssaType = ssaType.union(mapBaseType(baseType), compiler); | |
| 4683 } | |
| 4684 if (ssaType.isConflicting()) return HType.UNKNOWN; | |
| 4685 return ssaType; | |
| 4686 } | |
| 4687 | |
| 4688 HType getGuaranteedTypeOfElement(Element element) { | |
| 4689 return mapInferredType( | |
| 4690 compiler.typesTask.getGuaranteedTypeOfElement(element)); | |
| 4691 } | |
| 4692 | |
| 4693 // [type] is either an instance of [DartType] or special objects | |
| 4694 // like [native.SpecialType.JsObject], or [native.SpecialType.JsArray]. | |
| 4695 HType mapNativeType(type) { | |
| 4696 if (type == native.SpecialType.JsObject) { | |
| 4697 return new HType.nonNullExactClass( | |
| 4698 compiler.objectClass.computeType(compiler), compiler); | |
| 4699 } else if (type == native.SpecialType.JsArray) { | |
| 4700 return HType.READABLE_ARRAY; | |
| 4701 } else { | |
| 4702 return new HType.nonNullSubclass(type, compiler); | |
| 4703 } | |
| 4704 } | |
| 4705 | |
| 4706 HType mapNativeBehaviorType(native.NativeBehavior nativeBehavior) { | |
| 4707 if (nativeBehavior.typesInstantiated.isEmpty) return HType.UNKNOWN; | |
| 4708 | |
| 4709 HType ssaType = HType.CONFLICTING; | |
| 4710 for (final type in nativeBehavior.typesInstantiated) { | |
| 4711 ssaType = ssaType.union(mapNativeType(type), compiler); | |
| 4712 } | |
| 4713 assert(!ssaType.isConflicting()); | |
| 4714 return ssaType; | |
| 4715 } | |
| 4716 } | 4659 } |
| 4717 | 4660 |
| 4718 /** | 4661 /** |
| 4719 * Visitor that handles generation of string literals (LiteralString, | 4662 * Visitor that handles generation of string literals (LiteralString, |
| 4720 * StringInterpolation), and otherwise delegates to the given visitor for | 4663 * StringInterpolation), and otherwise delegates to the given visitor for |
| 4721 * non-literal subexpressions. | 4664 * non-literal subexpressions. |
| 4722 * TODO(lrn): Consider whether to handle compile time constant int/boolean | 4665 * TODO(lrn): Consider whether to handle compile time constant int/boolean |
| 4723 * expressions as well. | 4666 * expressions as well. |
| 4724 */ | 4667 */ |
| 4725 class StringBuilderVisitor extends Visitor { | 4668 class StringBuilderVisitor extends Visitor { |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5094 new HSubGraphBlockInformation(elseBranch.graph)); | 5037 new HSubGraphBlockInformation(elseBranch.graph)); |
| 5095 | 5038 |
| 5096 HBasicBlock conditionStartBlock = conditionBranch.block; | 5039 HBasicBlock conditionStartBlock = conditionBranch.block; |
| 5097 conditionStartBlock.setBlockFlow(info, joinBlock); | 5040 conditionStartBlock.setBlockFlow(info, joinBlock); |
| 5098 SubGraph conditionGraph = conditionBranch.graph; | 5041 SubGraph conditionGraph = conditionBranch.graph; |
| 5099 HIf branch = conditionGraph.end.last; | 5042 HIf branch = conditionGraph.end.last; |
| 5100 assert(branch is HIf); | 5043 assert(branch is HIf); |
| 5101 branch.blockInformation = conditionStartBlock.blockFlow; | 5044 branch.blockInformation = conditionStartBlock.blockFlow; |
| 5102 } | 5045 } |
| 5103 } | 5046 } |
| OLD | NEW |