Chromium Code Reviews| 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 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 405 // accessed through a closure-field. | 405 // accessed through a closure-field. |
| 406 // Calling [readLocal] makes sure we generate the correct code to get | 406 // Calling [readLocal] makes sure we generate the correct code to get |
| 407 // the box. | 407 // the box. |
| 408 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); | 408 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); |
| 409 HInstruction box = readLocal(redirect.enclosingElement); | 409 HInstruction box = readLocal(redirect.enclosingElement); |
| 410 HInstruction lookup = new HFieldGet(redirect.name, box); | 410 HInstruction lookup = new HFieldGet(redirect.name, box); |
| 411 builder.add(lookup); | 411 builder.add(lookup); |
| 412 return lookup; | 412 return lookup; |
| 413 } else { | 413 } else { |
| 414 assert(isUsedInTry(element)); | 414 assert(isUsedInTry(element)); |
| 415 HInstruction variable = new HFieldGet.fromActivation(element.name); | 415 HParameterValue parameter = builder.activationVariables.putIfAbsent( |
|
kasperl
2012/05/25 10:05:15
This code should be refactored. There's a lot of d
ngeoffray
2012/05/25 10:45:10
Done.
| |
| 416 element, () { | |
| 417 HParameterValue parameter = new HParameterValue(element); | |
| 418 builder.add(parameter); | |
| 419 return parameter; | |
| 420 } | |
| 421 ); | |
| 422 HInstruction variable = new HFieldGet.fromActivation(parameter); | |
| 416 builder.add(variable); | 423 builder.add(variable); |
| 417 return variable; | 424 return variable; |
| 418 } | 425 } |
| 419 } | 426 } |
| 420 | 427 |
| 421 HType cachedTypeOfThis; | 428 HType cachedTypeOfThis; |
| 422 | 429 |
| 423 HInstruction readThis() { | 430 HInstruction readThis() { |
| 424 HInstruction res = readLocal(closureData.thisElement); | 431 HInstruction res = readLocal(closureData.thisElement); |
| 425 if (res.guaranteedType === null) { | 432 if (res.guaranteedType === null) { |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 454 Element redirect = redirectionMapping[element]; | 461 Element redirect = redirectionMapping[element]; |
| 455 // The box itself could be captured, or be local. A local variable that | 462 // The box itself could be captured, or be local. A local variable that |
| 456 // is captured will be boxed, but the box itself will be a local. | 463 // is captured will be boxed, but the box itself will be a local. |
| 457 // Inside the closure the box is stored in a closure-field and cannot | 464 // Inside the closure the box is stored in a closure-field and cannot |
| 458 // be accessed directly. | 465 // be accessed directly. |
| 459 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); | 466 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); |
| 460 HInstruction box = readLocal(redirect.enclosingElement); | 467 HInstruction box = readLocal(redirect.enclosingElement); |
| 461 builder.add(new HFieldSet(redirect.name, box, value)); | 468 builder.add(new HFieldSet(redirect.name, box, value)); |
| 462 } else { | 469 } else { |
| 463 assert(isUsedInTry(element)); | 470 assert(isUsedInTry(element)); |
| 464 builder.add(new HFieldSet.fromActivation(element.name, value)); | 471 HParameterValue parameter = builder.activationVariables.putIfAbsent( |
| 472 element, () { | |
| 473 HParameterValue parameter = new HParameterValue(element); | |
| 474 builder.add(parameter); | |
| 475 return parameter; | |
| 476 } | |
| 477 ); | |
| 478 builder.add(new HFieldSet.fromActivation(parameter, value)); | |
| 465 } | 479 } |
| 466 } | 480 } |
| 467 | 481 |
| 468 /** | 482 /** |
| 469 * This function must be called before visiting any children of the loop. In | 483 * This function must be called before visiting any children of the loop. In |
| 470 * particular it needs to be called before executing the initializers. | 484 * particular it needs to be called before executing the initializers. |
| 471 * | 485 * |
| 472 * The [LocalsHandler] will make the boxes and updates at the right moment. | 486 * The [LocalsHandler] will make the boxes and updates at the right moment. |
| 473 * The builder just needs to call [enterLoopBody] and [enterLoopUpdates] (for | 487 * The builder just needs to call [enterLoopBody] and [enterLoopUpdates] (for |
| 474 * [For] loops) at the correct places. For phi-handling [beginLoopHeader] and | 488 * [For] loops) at the correct places. For phi-handling [beginLoopHeader] and |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 772 TreeElements elements; | 786 TreeElements elements; |
| 773 final Interceptors interceptors; | 787 final Interceptors interceptors; |
| 774 final WorkItem work; | 788 final WorkItem work; |
| 775 bool methodInterceptionEnabled; | 789 bool methodInterceptionEnabled; |
| 776 HGraph graph; | 790 HGraph graph; |
| 777 LocalsHandler localsHandler; | 791 LocalsHandler localsHandler; |
| 778 HInstruction rethrowableException; | 792 HInstruction rethrowableException; |
| 779 | 793 |
| 780 Map<TargetElement, JumpHandler> jumpTargets; | 794 Map<TargetElement, JumpHandler> jumpTargets; |
| 781 | 795 |
| 796 /** | |
| 797 * Variables stored in the current activation. These variables are | |
| 798 * being updated in try/catch blocks, and should be | |
| 799 * accessed indirectly through HFieldGet and HFieldSet. | |
| 800 */ | |
| 801 Map<Element, HParameterValue> activationVariables; | |
| 802 | |
| 782 // We build the Ssa graph by simulating a stack machine. | 803 // We build the Ssa graph by simulating a stack machine. |
| 783 List<HInstruction> stack; | 804 List<HInstruction> stack; |
| 784 | 805 |
| 785 // The current block to add instructions to. Might be null, if we are | 806 // The current block to add instructions to. Might be null, if we are |
| 786 // visiting dead code. | 807 // visiting dead code. |
| 787 HBasicBlock current; | 808 HBasicBlock current; |
| 788 // The most recently opened block. Has the same value as [current] while | 809 // The most recently opened block. Has the same value as [current] while |
| 789 // the block is open, but unlike [current], it isn't cleared when the current | 810 // the block is open, but unlike [current], it isn't cleared when the current |
| 790 // block is closed. | 811 // block is closed. |
| 791 HBasicBlock lastOpenedBlock; | 812 HBasicBlock lastOpenedBlock; |
| 792 | 813 |
| 793 LibraryElement get currentLibrary() => work.element.getLibrary(); | 814 LibraryElement get currentLibrary() => work.element.getLibrary(); |
| 794 Compiler get compiler() => builder.compiler; | 815 Compiler get compiler() => builder.compiler; |
| 795 CodeEmitterTask get emitter() => builder.emitter; | 816 CodeEmitterTask get emitter() => builder.emitter; |
| 796 | 817 |
| 797 SsaBuilder(SsaBuilderTask builder, WorkItem work) | 818 SsaBuilder(SsaBuilderTask builder, WorkItem work) |
| 798 : this.builder = builder, | 819 : this.builder = builder, |
| 799 this.work = work, | 820 this.work = work, |
| 800 interceptors = builder.interceptors, | 821 interceptors = builder.interceptors, |
| 801 methodInterceptionEnabled = true, | 822 methodInterceptionEnabled = true, |
| 802 elements = work.resolutionTree, | 823 elements = work.resolutionTree, |
| 803 graph = new HGraph(), | 824 graph = new HGraph(), |
| 804 stack = new List<HInstruction>(), | 825 stack = new List<HInstruction>(), |
| 826 activationVariables = new Map<Element, HParameterValue>(), | |
| 805 jumpTargets = new Map<TargetElement, JumpHandler>() { | 827 jumpTargets = new Map<TargetElement, JumpHandler>() { |
| 806 localsHandler = new LocalsHandler(this); | 828 localsHandler = new LocalsHandler(this); |
| 807 } | 829 } |
| 808 | 830 |
| 809 void disableMethodInterception() { | 831 void disableMethodInterception() { |
| 810 assert(methodInterceptionEnabled); | 832 assert(methodInterceptionEnabled); |
| 811 methodInterceptionEnabled = false; | 833 methodInterceptionEnabled = false; |
| 812 } | 834 } |
| 813 | 835 |
| 814 void enableMethodInterception() { | 836 void enableMethodInterception() { |
| (...skipping 2551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3366 <HInstruction>[target, input], | 3388 <HInstruction>[target, input], |
| 3367 HType.STRING)); | 3389 HType.STRING)); |
| 3368 return builder.pop(); | 3390 return builder.pop(); |
| 3369 } | 3391 } |
| 3370 | 3392 |
| 3371 HInstruction result(Node node) { | 3393 HInstruction result(Node node) { |
| 3372 flushLiterals(node); | 3394 flushLiterals(node); |
| 3373 return prefix; | 3395 return prefix; |
| 3374 } | 3396 } |
| 3375 } | 3397 } |
| OLD | NEW |