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 class Interceptors { | 5 class Interceptors { |
6 Compiler compiler; | 6 Compiler compiler; |
7 Interceptors(Compiler this.compiler); | 7 Interceptors(Compiler this.compiler); |
8 | 8 |
9 SourceString mapOperatorToMethodName(Operator op) { | 9 SourceString mapOperatorToMethodName(Operator op) { |
10 String name = op.source.stringValue; | 10 String name = op.source.stringValue; |
(...skipping 3406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3417 if (element == null || !identical(element.statement, node)) { | 3417 if (element == null || !identical(element.statement, node)) { |
3418 // No breaks or continues to this node. | 3418 // No breaks or continues to this node. |
3419 return new NullJumpHandler(compiler); | 3419 return new NullJumpHandler(compiler); |
3420 } | 3420 } |
3421 return new JumpHandler(this, element); | 3421 return new JumpHandler(this, element); |
3422 } | 3422 } |
3423 | 3423 |
3424 visitForIn(ForIn node) { | 3424 visitForIn(ForIn node) { |
3425 // Generate a structure equivalent to: | 3425 // Generate a structure equivalent to: |
3426 // Iterator<E> $iter = <iterable>.iterator() | 3426 // Iterator<E> $iter = <iterable>.iterator() |
3427 // while ($iter.hasNext()) { | 3427 // while ($iter.hasNext) { |
3428 // E <declaredIdentifier> = $iter.next(); | 3428 // E <declaredIdentifier> = $iter.next(); |
3429 // <body> | 3429 // <body> |
3430 // } | 3430 // } |
3431 | 3431 |
3432 // The iterator is shared between initializer, condition and body. | 3432 // The iterator is shared between initializer, condition and body. |
3433 HInstruction iterator; | 3433 HInstruction iterator; |
3434 void buildInitializer() { | 3434 void buildInitializer() { |
3435 SourceString iteratorName = const SourceString("iterator"); | 3435 SourceString iteratorName = const SourceString("iterator"); |
3436 Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0); | 3436 Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0); |
3437 assert(interceptor != null); | 3437 assert(interceptor != null); |
3438 visit(node.expression); | 3438 visit(node.expression); |
3439 pushInvokeHelper1(interceptor, pop()); | 3439 pushInvokeHelper1(interceptor, pop()); |
3440 iterator = pop(); | 3440 iterator = pop(); |
3441 } | 3441 } |
3442 HInstruction buildCondition() { | 3442 HInstruction buildCondition() { |
3443 SourceString name = const SourceString('hasNext'); | 3443 SourceString name = const SourceString('hasNext'); |
3444 Selector call = new Selector.call(name, work.element.getLibrary(), 0); | 3444 Selector selector = new Selector.getter(name, work.element.getLibrary()); |
3445 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); | 3445 if (interceptors.getStaticGetInterceptor(name) != null) { |
| 3446 compiler.internalError("hasNext getter must not be intercepted", |
| 3447 node: node); |
| 3448 } |
| 3449 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); |
| 3450 push(new HInvokeDynamicGetter(selector, null, iterator, !hasGetter)); |
3446 return popBoolified(); | 3451 return popBoolified(); |
3447 } | 3452 } |
3448 void buildBody() { | 3453 void buildBody() { |
3449 SourceString name = const SourceString('next'); | 3454 SourceString name = const SourceString('next'); |
3450 Selector call = new Selector.call(name, work.element.getLibrary(), 0); | 3455 Selector call = new Selector.call(name, work.element.getLibrary(), 0); |
3451 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); | 3456 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); |
3452 | 3457 |
3453 Element variable; | 3458 Element variable; |
3454 if (node.declaredIdentifier.asSend() != null) { | 3459 if (node.declaredIdentifier.asSend() != null) { |
3455 variable = elements[node.declaredIdentifier]; | 3460 variable = elements[node.declaredIdentifier]; |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3670 HBasicBlock expressionBlock = close(switchInstruction); | 3675 HBasicBlock expressionBlock = close(switchInstruction); |
3671 JumpHandler jumpHandler = createJumpHandler(node); | 3676 JumpHandler jumpHandler = createJumpHandler(node); |
3672 LocalsHandler savedLocals = localsHandler; | 3677 LocalsHandler savedLocals = localsHandler; |
3673 | 3678 |
3674 List<List<Constant>> matchExpressions = <List<Constant>>[]; | 3679 List<List<Constant>> matchExpressions = <List<Constant>>[]; |
3675 List<HStatementInformation> statements = <HStatementInformation>[]; | 3680 List<HStatementInformation> statements = <HStatementInformation>[]; |
3676 bool hasDefault = false; | 3681 bool hasDefault = false; |
3677 Element getFallThroughErrorElement = | 3682 Element getFallThroughErrorElement = |
3678 compiler.findHelper(const SourceString("getFallThroughError")); | 3683 compiler.findHelper(const SourceString("getFallThroughError")); |
3679 Iterator<Node> caseIterator = node.cases.iterator(); | 3684 Iterator<Node> caseIterator = node.cases.iterator(); |
3680 while (caseIterator.hasNext()) { | 3685 while (caseIterator.hasNext) { |
3681 SwitchCase switchCase = caseIterator.next(); | 3686 SwitchCase switchCase = caseIterator.next(); |
3682 List<Constant> caseConstants = <Constant>[]; | 3687 List<Constant> caseConstants = <Constant>[]; |
3683 HBasicBlock block = graph.addNewBlock(); | 3688 HBasicBlock block = graph.addNewBlock(); |
3684 for (Node labelOrCase in switchCase.labelsAndCases) { | 3689 for (Node labelOrCase in switchCase.labelsAndCases) { |
3685 if (labelOrCase is CaseMatch) { | 3690 if (labelOrCase is CaseMatch) { |
3686 Constant constant = constants[labelOrCase]; | 3691 Constant constant = constants[labelOrCase]; |
3687 caseConstants.add(constant); | 3692 caseConstants.add(constant); |
3688 HConstant hConstant = graph.addConstant(constant); | 3693 HConstant hConstant = graph.addConstant(constant); |
3689 switchInstruction.inputs.add(hConstant); | 3694 switchInstruction.inputs.add(hConstant); |
3690 hConstant.usedBy.add(switchInstruction); | 3695 hConstant.usedBy.add(switchInstruction); |
3691 expressionBlock.addSuccessor(block); | 3696 expressionBlock.addSuccessor(block); |
3692 } | 3697 } |
3693 } | 3698 } |
3694 matchExpressions.add(caseConstants); | 3699 matchExpressions.add(caseConstants); |
3695 | 3700 |
3696 if (switchCase.isDefaultCase) { | 3701 if (switchCase.isDefaultCase) { |
3697 // An HSwitch has n inputs and n+1 successors, the last being the | 3702 // An HSwitch has n inputs and n+1 successors, the last being the |
3698 // default case. | 3703 // default case. |
3699 expressionBlock.addSuccessor(block); | 3704 expressionBlock.addSuccessor(block); |
3700 hasDefault = true; | 3705 hasDefault = true; |
3701 } | 3706 } |
3702 open(block); | 3707 open(block); |
3703 localsHandler = new LocalsHandler.from(savedLocals); | 3708 localsHandler = new LocalsHandler.from(savedLocals); |
3704 visit(switchCase.statements); | 3709 visit(switchCase.statements); |
3705 if (!isAborted() && caseIterator.hasNext()) { | 3710 if (!isAborted() && caseIterator.hasNext) { |
3706 pushInvokeHelper0(getFallThroughErrorElement); | 3711 pushInvokeHelper0(getFallThroughErrorElement); |
3707 HInstruction error = pop(); | 3712 HInstruction error = pop(); |
3708 close(new HThrow(error)); | 3713 close(new HThrow(error)); |
3709 } | 3714 } |
3710 statements.add( | 3715 statements.add( |
3711 new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock))); | 3716 new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock))); |
3712 } | 3717 } |
3713 | 3718 |
3714 // Add a join-block if necessary. | 3719 // Add a join-block if necessary. |
3715 // We create [joinBlock] early, and then go through the cases that might | 3720 // We create [joinBlock] early, and then go through the cases that might |
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4498 new HSubGraphBlockInformation(elseBranch.graph)); | 4503 new HSubGraphBlockInformation(elseBranch.graph)); |
4499 | 4504 |
4500 HBasicBlock conditionStartBlock = conditionBranch.block; | 4505 HBasicBlock conditionStartBlock = conditionBranch.block; |
4501 conditionStartBlock.setBlockFlow(info, joinBlock); | 4506 conditionStartBlock.setBlockFlow(info, joinBlock); |
4502 SubGraph conditionGraph = conditionBranch.graph; | 4507 SubGraph conditionGraph = conditionBranch.graph; |
4503 HIf branch = conditionGraph.end.last; | 4508 HIf branch = conditionGraph.end.last; |
4504 assert(branch is HIf); | 4509 assert(branch is HIf); |
4505 branch.blockInformation = conditionStartBlock.blockFlow; | 4510 branch.blockInformation = conditionStartBlock.blockFlow; |
4506 } | 4511 } |
4507 } | 4512 } |
OLD | NEW |