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 3955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3966 TargetElement element = elements[node]; | 3966 TargetElement element = elements[node]; |
3967 if (element == null || !identical(element.statement, node)) { | 3967 if (element == null || !identical(element.statement, node)) { |
3968 // No breaks or continues to this node. | 3968 // No breaks or continues to this node. |
3969 return new NullJumpHandler(compiler); | 3969 return new NullJumpHandler(compiler); |
3970 } | 3970 } |
3971 return new JumpHandler(this, element); | 3971 return new JumpHandler(this, element); |
3972 } | 3972 } |
3973 | 3973 |
3974 visitForIn(ForIn node) { | 3974 visitForIn(ForIn node) { |
3975 // Generate a structure equivalent to: | 3975 // Generate a structure equivalent to: |
3976 // Iterator<E> $iter = <iterable>.iterator() | 3976 // Iterator<E> $iter = <iterable>.iterator; |
3977 // while ($iter.hasNext) { | 3977 // while ($iter.moveNext()) { |
3978 // E <declaredIdentifier> = $iter.next(); | 3978 // E <declaredIdentifier> = $iter.current; |
3979 // <body> | 3979 // <body> |
3980 // } | 3980 // } |
3981 | 3981 |
3982 // The iterator is shared between initializer, condition and body. | 3982 // The iterator is shared between initializer, condition and body. |
3983 HInstruction iterator; | 3983 HInstruction iterator; |
3984 void buildInitializer() { | 3984 void buildInitializer() { |
3985 SourceString iteratorName = const SourceString("iterator"); | 3985 SourceString iteratorName = const SourceString("iterator"); |
3986 Selector selector = | 3986 Selector selector = |
3987 new Selector.call(iteratorName, work.element.getLibrary(), 0); | 3987 new Selector.getter(iteratorName, work.element.getLibrary()); |
3988 Set<ClassElement> interceptedClasses = | 3988 Set<ClassElement> interceptedClasses = |
3989 interceptors.getInterceptedClassesOn(selector); | 3989 interceptors.getInterceptedClassesOn(selector); |
3990 visit(node.expression); | 3990 visit(node.expression); |
3991 HInstruction receiver = pop(); | 3991 HInstruction receiver = pop(); |
| 3992 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); |
3992 if (interceptedClasses == null) { | 3993 if (interceptedClasses == null) { |
3993 iterator = new HInvokeDynamicMethod(selector, <HInstruction>[receiver]); | 3994 iterator = |
| 3995 new HInvokeDynamicGetter(selector, null, receiver, hasGetter); |
3994 } else { | 3996 } else { |
3995 HInterceptor interceptor = | 3997 HInterceptor interceptor = |
3996 invokeInterceptor(interceptedClasses, receiver, null); | 3998 invokeInterceptor(interceptedClasses, receiver, null); |
3997 iterator = new HInvokeDynamicMethod( | 3999 iterator = |
3998 selector, <HInstruction>[interceptor, receiver]); | 4000 new HInvokeDynamicGetter(selector, null, interceptor, hasGetter); |
| 4001 // Add the receiver as an argument to the getter call on the |
| 4002 // interceptor. |
| 4003 iterator.inputs.add(receiver); |
3999 } | 4004 } |
4000 add(iterator); | 4005 add(iterator); |
4001 } | 4006 } |
4002 HInstruction buildCondition() { | 4007 HInstruction buildCondition() { |
4003 SourceString name = const SourceString('hasNext'); | 4008 SourceString name = const SourceString('moveNext'); |
4004 Selector selector = new Selector.getter(name, work.element.getLibrary()); | 4009 Selector selector = new Selector.call(name, work.element.getLibrary(), 0); |
4005 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); | 4010 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); |
4006 push(new HInvokeDynamicGetter(selector, null, iterator, !hasGetter)); | 4011 push(new HInvokeDynamicMethod(selector, <HInstruction>[iterator])); |
4007 return popBoolified(); | 4012 return popBoolified(); |
4008 } | 4013 } |
4009 void buildBody() { | 4014 void buildBody() { |
4010 SourceString name = const SourceString('next'); | 4015 SourceString name = const SourceString('current'); |
4011 Selector call = new Selector.call(name, work.element.getLibrary(), 0); | 4016 Selector call = new Selector.getter(name, work.element.getLibrary()); |
4012 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); | 4017 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(call); |
| 4018 push(new HInvokeDynamicGetter(call, null, iterator, hasGetter)); |
4013 | 4019 |
4014 Element variable; | 4020 Element variable; |
4015 if (node.declaredIdentifier.asSend() != null) { | 4021 if (node.declaredIdentifier.asSend() != null) { |
4016 variable = elements[node.declaredIdentifier]; | 4022 variable = elements[node.declaredIdentifier]; |
4017 } else { | 4023 } else { |
4018 assert(node.declaredIdentifier.asVariableDefinitions() != null); | 4024 assert(node.declaredIdentifier.asVariableDefinitions() != null); |
4019 VariableDefinitions variableDefinitions = node.declaredIdentifier; | 4025 VariableDefinitions variableDefinitions = node.declaredIdentifier; |
4020 variable = elements[variableDefinitions.definitions.nodes.head]; | 4026 variable = elements[variableDefinitions.definitions.nodes.head]; |
4021 } | 4027 } |
4022 HInstruction oldVariable = pop(); | 4028 HInstruction oldVariable = pop(); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4230 HSwitch switchInstruction = new HSwitch(<HInstruction>[expression]); | 4236 HSwitch switchInstruction = new HSwitch(<HInstruction>[expression]); |
4231 HBasicBlock expressionBlock = close(switchInstruction); | 4237 HBasicBlock expressionBlock = close(switchInstruction); |
4232 JumpHandler jumpHandler = createJumpHandler(node); | 4238 JumpHandler jumpHandler = createJumpHandler(node); |
4233 LocalsHandler savedLocals = localsHandler; | 4239 LocalsHandler savedLocals = localsHandler; |
4234 | 4240 |
4235 List<List<Constant>> matchExpressions = <List<Constant>>[]; | 4241 List<List<Constant>> matchExpressions = <List<Constant>>[]; |
4236 List<HStatementInformation> statements = <HStatementInformation>[]; | 4242 List<HStatementInformation> statements = <HStatementInformation>[]; |
4237 bool hasDefault = false; | 4243 bool hasDefault = false; |
4238 Element getFallThroughErrorElement = | 4244 Element getFallThroughErrorElement = |
4239 compiler.findHelper(const SourceString("getFallThroughError")); | 4245 compiler.findHelper(const SourceString("getFallThroughError")); |
4240 Iterator<Node> caseIterator = node.cases.iterator(); | 4246 HasNextIterator<Node> caseIterator = |
| 4247 new HasNextIterator<Node>(node.cases.iterator); |
4241 while (caseIterator.hasNext) { | 4248 while (caseIterator.hasNext) { |
4242 SwitchCase switchCase = caseIterator.next(); | 4249 SwitchCase switchCase = caseIterator.next(); |
4243 List<Constant> caseConstants = <Constant>[]; | 4250 List<Constant> caseConstants = <Constant>[]; |
4244 HBasicBlock block = graph.addNewBlock(); | 4251 HBasicBlock block = graph.addNewBlock(); |
4245 for (Node labelOrCase in switchCase.labelsAndCases) { | 4252 for (Node labelOrCase in switchCase.labelsAndCases) { |
4246 if (labelOrCase is CaseMatch) { | 4253 if (labelOrCase is CaseMatch) { |
4247 Constant constant = constants[labelOrCase]; | 4254 Constant constant = constants[labelOrCase]; |
4248 caseConstants.add(constant); | 4255 caseConstants.add(constant); |
4249 HConstant hConstant = graph.addConstant(constant); | 4256 HConstant hConstant = graph.addConstant(constant); |
4250 switchInstruction.inputs.add(hConstant); | 4257 switchInstruction.inputs.add(hConstant); |
(...skipping 823 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5074 new HSubGraphBlockInformation(elseBranch.graph)); | 5081 new HSubGraphBlockInformation(elseBranch.graph)); |
5075 | 5082 |
5076 HBasicBlock conditionStartBlock = conditionBranch.block; | 5083 HBasicBlock conditionStartBlock = conditionBranch.block; |
5077 conditionStartBlock.setBlockFlow(info, joinBlock); | 5084 conditionStartBlock.setBlockFlow(info, joinBlock); |
5078 SubGraph conditionGraph = conditionBranch.graph; | 5085 SubGraph conditionGraph = conditionBranch.graph; |
5079 HIf branch = conditionGraph.end.last; | 5086 HIf branch = conditionGraph.end.last; |
5080 assert(branch is HIf); | 5087 assert(branch is HIf); |
5081 branch.blockInformation = conditionStartBlock.blockFlow; | 5088 branch.blockInformation = conditionStartBlock.blockFlow; |
5082 } | 5089 } |
5083 } | 5090 } |
OLD | NEW |