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 3394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3405 if (element == null || !identical(element.statement, node)) { | 3405 if (element == null || !identical(element.statement, node)) { |
3406 // No breaks or continues to this node. | 3406 // No breaks or continues to this node. |
3407 return new NullJumpHandler(compiler); | 3407 return new NullJumpHandler(compiler); |
3408 } | 3408 } |
3409 return new JumpHandler(this, element); | 3409 return new JumpHandler(this, element); |
3410 } | 3410 } |
3411 | 3411 |
3412 visitForIn(ForIn node) { | 3412 visitForIn(ForIn node) { |
3413 // Generate a structure equivalent to: | 3413 // Generate a structure equivalent to: |
3414 // Iterator<E> $iter = <iterable>.iterator() | 3414 // Iterator<E> $iter = <iterable>.iterator() |
3415 // while ($iter.hasNext()) { | 3415 // while ($iter.hasNext) { |
3416 // E <declaredIdentifier> = $iter.next(); | 3416 // E <declaredIdentifier> = $iter.next(); |
3417 // <body> | 3417 // <body> |
3418 // } | 3418 // } |
3419 | 3419 |
3420 // The iterator is shared between initializer, condition and body. | 3420 // The iterator is shared between initializer, condition and body. |
3421 HInstruction iterator; | 3421 HInstruction iterator; |
3422 void buildInitializer() { | 3422 void buildInitializer() { |
3423 SourceString iteratorName = const SourceString("iterator"); | 3423 SourceString iteratorName = const SourceString("iterator"); |
3424 Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0); | 3424 Element interceptor = interceptors.getStaticInterceptor(iteratorName, 0); |
3425 assert(interceptor != null); | 3425 assert(interceptor != null); |
3426 visit(node.expression); | 3426 visit(node.expression); |
3427 pushInvokeHelper1(interceptor, pop()); | 3427 pushInvokeHelper1(interceptor, pop()); |
3428 iterator = pop(); | 3428 iterator = pop(); |
3429 } | 3429 } |
3430 HInstruction buildCondition() { | 3430 HInstruction buildCondition() { |
3431 SourceString name = const SourceString('hasNext'); | 3431 SourceString name = const SourceString('hasNext'); |
3432 Selector call = new Selector.call(name, work.element.getLibrary(), 0); | 3432 Selector selector = new Selector.getter(name, work.element.getLibrary()); |
3433 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); | 3433 Element staticInterceptor = null; |
Lasse Reichstein Nielsen
2012/10/20 11:22:42
I this variable used?
floitsch
2012/10/24 13:02:47
Done.
| |
3434 if (interceptors.getStaticGetInterceptor(name) != null) { | |
3435 compiler.internalError("hasNext getter must not be intercepted", | |
3436 node: node); | |
3437 } | |
3438 bool hasGetter = compiler.world.hasAnyUserDefinedGetter(selector); | |
3439 push(new HInvokeDynamicGetter(selector, null, iterator, !hasGetter)); | |
3434 return popBoolified(); | 3440 return popBoolified(); |
3435 } | 3441 } |
3436 void buildBody() { | 3442 void buildBody() { |
3437 SourceString name = const SourceString('next'); | 3443 SourceString name = const SourceString('next'); |
3438 Selector call = new Selector.call(name, work.element.getLibrary(), 0); | 3444 Selector call = new Selector.call(name, work.element.getLibrary(), 0); |
3439 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); | 3445 push(new HInvokeDynamicMethod(call, <HInstruction>[iterator])); |
3440 | 3446 |
3441 Element variable; | 3447 Element variable; |
3442 if (node.declaredIdentifier.asSend() != null) { | 3448 if (node.declaredIdentifier.asSend() != null) { |
3443 variable = elements[node.declaredIdentifier]; | 3449 variable = elements[node.declaredIdentifier]; |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3658 HBasicBlock expressionBlock = close(switchInstruction); | 3664 HBasicBlock expressionBlock = close(switchInstruction); |
3659 JumpHandler jumpHandler = createJumpHandler(node); | 3665 JumpHandler jumpHandler = createJumpHandler(node); |
3660 LocalsHandler savedLocals = localsHandler; | 3666 LocalsHandler savedLocals = localsHandler; |
3661 | 3667 |
3662 List<List<Constant>> matchExpressions = <List<Constant>>[]; | 3668 List<List<Constant>> matchExpressions = <List<Constant>>[]; |
3663 List<HStatementInformation> statements = <HStatementInformation>[]; | 3669 List<HStatementInformation> statements = <HStatementInformation>[]; |
3664 bool hasDefault = false; | 3670 bool hasDefault = false; |
3665 Element getFallThroughErrorElement = | 3671 Element getFallThroughErrorElement = |
3666 compiler.findHelper(const SourceString("getFallThroughError")); | 3672 compiler.findHelper(const SourceString("getFallThroughError")); |
3667 Iterator<Node> caseIterator = node.cases.iterator(); | 3673 Iterator<Node> caseIterator = node.cases.iterator(); |
3668 while (caseIterator.hasNext()) { | 3674 while (caseIterator.hasNext) { |
3669 SwitchCase switchCase = caseIterator.next(); | 3675 SwitchCase switchCase = caseIterator.next(); |
3670 List<Constant> caseConstants = <Constant>[]; | 3676 List<Constant> caseConstants = <Constant>[]; |
3671 HBasicBlock block = graph.addNewBlock(); | 3677 HBasicBlock block = graph.addNewBlock(); |
3672 for (Node labelOrCase in switchCase.labelsAndCases) { | 3678 for (Node labelOrCase in switchCase.labelsAndCases) { |
3673 if (labelOrCase is CaseMatch) { | 3679 if (labelOrCase is CaseMatch) { |
3674 Constant constant = constants[labelOrCase]; | 3680 Constant constant = constants[labelOrCase]; |
3675 caseConstants.add(constant); | 3681 caseConstants.add(constant); |
3676 HConstant hConstant = graph.addConstant(constant); | 3682 HConstant hConstant = graph.addConstant(constant); |
3677 switchInstruction.inputs.add(hConstant); | 3683 switchInstruction.inputs.add(hConstant); |
3678 hConstant.usedBy.add(switchInstruction); | 3684 hConstant.usedBy.add(switchInstruction); |
3679 expressionBlock.addSuccessor(block); | 3685 expressionBlock.addSuccessor(block); |
3680 } | 3686 } |
3681 } | 3687 } |
3682 matchExpressions.add(caseConstants); | 3688 matchExpressions.add(caseConstants); |
3683 | 3689 |
3684 if (switchCase.isDefaultCase) { | 3690 if (switchCase.isDefaultCase) { |
3685 // An HSwitch has n inputs and n+1 successors, the last being the | 3691 // An HSwitch has n inputs and n+1 successors, the last being the |
3686 // default case. | 3692 // default case. |
3687 expressionBlock.addSuccessor(block); | 3693 expressionBlock.addSuccessor(block); |
3688 hasDefault = true; | 3694 hasDefault = true; |
3689 } | 3695 } |
3690 open(block); | 3696 open(block); |
3691 localsHandler = new LocalsHandler.from(savedLocals); | 3697 localsHandler = new LocalsHandler.from(savedLocals); |
3692 visit(switchCase.statements); | 3698 visit(switchCase.statements); |
3693 if (!isAborted() && caseIterator.hasNext()) { | 3699 if (!isAborted() && caseIterator.hasNext) { |
3694 pushInvokeHelper0(getFallThroughErrorElement); | 3700 pushInvokeHelper0(getFallThroughErrorElement); |
3695 HInstruction error = pop(); | 3701 HInstruction error = pop(); |
3696 close(new HThrow(error)); | 3702 close(new HThrow(error)); |
3697 } | 3703 } |
3698 statements.add( | 3704 statements.add( |
3699 new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock))); | 3705 new HSubGraphBlockInformation(new SubGraph(block, lastOpenedBlock))); |
3700 } | 3706 } |
3701 | 3707 |
3702 // Add a join-block if necessary. | 3708 // Add a join-block if necessary. |
3703 // We create [joinBlock] early, and then go through the cases that might | 3709 // 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... | |
4486 new HSubGraphBlockInformation(elseBranch.graph)); | 4492 new HSubGraphBlockInformation(elseBranch.graph)); |
4487 | 4493 |
4488 HBasicBlock conditionStartBlock = conditionBranch.block; | 4494 HBasicBlock conditionStartBlock = conditionBranch.block; |
4489 conditionStartBlock.setBlockFlow(info, joinBlock); | 4495 conditionStartBlock.setBlockFlow(info, joinBlock); |
4490 SubGraph conditionGraph = conditionBranch.graph; | 4496 SubGraph conditionGraph = conditionBranch.graph; |
4491 HIf branch = conditionGraph.end.last; | 4497 HIf branch = conditionGraph.end.last; |
4492 assert(branch is HIf); | 4498 assert(branch is HIf); |
4493 branch.blockInformation = conditionStartBlock.blockFlow; | 4499 branch.blockInformation = conditionStartBlock.blockFlow; |
4494 } | 4500 } |
4495 } | 4501 } |
OLD | NEW |