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 HParameterValue parameter = getActivationParameter(element); | 415 HInstruction instruction = getActivationValue(element); |
| 416 HInstruction variable = new HFieldGet.fromActivation(parameter); | 416 HInstruction variable = new HFieldGet.fromActivation(instruction); |
| 417 builder.add(variable); | 417 builder.add(variable); |
| 418 return variable; | 418 return variable; |
| 419 } | 419 } |
| 420 } | 420 } |
| 421 | 421 |
| 422 HType cachedTypeOfThis; | 422 HType cachedTypeOfThis; |
| 423 | 423 |
| 424 HInstruction readThis() { | 424 HInstruction readThis() { |
| 425 HInstruction res = readLocal(closureData.thisElement); | 425 HInstruction res = readLocal(closureData.thisElement); |
| 426 if (res.guaranteedType === null) { | 426 if (res.guaranteedType === null) { |
| 427 if (cachedTypeOfThis === null) { | 427 if (cachedTypeOfThis === null) { |
| 428 assert(closureData.isClosure()); | 428 assert(closureData.isClosure()); |
| 429 Element element = closureData.thisElement; | 429 Element element = closureData.thisElement; |
| 430 ClassElement cls = element.enclosingElement.enclosingElement; | 430 ClassElement cls = element.enclosingElement.enclosingElement; |
| 431 Type type = cls.computeType(builder.compiler); | 431 Type type = cls.computeType(builder.compiler); |
| 432 cachedTypeOfThis = new HBoundedType(type); | 432 cachedTypeOfThis = new HBoundedType(type); |
| 433 } | 433 } |
| 434 res.guaranteedType = cachedTypeOfThis; | 434 res.guaranteedType = cachedTypeOfThis; |
| 435 } | 435 } |
| 436 return res; | 436 return res; |
| 437 } | 437 } |
| 438 | 438 |
| 439 HParameterValue getActivationParameter(Element element) { | 439 HInstruction getActivationValue(Element element) { |
| 440 if (element.isParameter()) { | 440 if (element.isParameter()) return directLocals[element]; |
|
floitsch
2012/05/29 18:31:38
Please add comment what is happening here.
ngeoffray
2012/05/30 08:31:45
Done.
| |
| 441 HInstruction instruction = directLocals[element]; | |
| 442 if (instruction is HParameterValue) return instruction; | |
| 443 } | |
| 444 | 441 |
| 445 return builder.activationVariables.putIfAbsent(element, () { | 442 return builder.activationVariables.putIfAbsent(element, () { |
| 446 HParameterValue parameter = new HParameterValue(element); | 443 HParameterValue parameter = new HParameterValue(element); |
| 447 builder.graph.entry.addAtExit(parameter); | 444 builder.graph.entry.addAtExit(parameter); |
| 448 return parameter; | 445 return parameter; |
| 449 }); | 446 }); |
| 450 } | 447 } |
| 451 | 448 |
| 452 /** | 449 /** |
| 453 * Sets the [element] to [value]. If the element is boxed or stored in a | 450 * Sets the [element] to [value]. If the element is boxed or stored in a |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 468 Element redirect = redirectionMapping[element]; | 465 Element redirect = redirectionMapping[element]; |
| 469 // The box itself could be captured, or be local. A local variable that | 466 // The box itself could be captured, or be local. A local variable that |
| 470 // is captured will be boxed, but the box itself will be a local. | 467 // is captured will be boxed, but the box itself will be a local. |
| 471 // Inside the closure the box is stored in a closure-field and cannot | 468 // Inside the closure the box is stored in a closure-field and cannot |
| 472 // be accessed directly. | 469 // be accessed directly. |
| 473 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); | 470 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); |
| 474 HInstruction box = readLocal(redirect.enclosingElement); | 471 HInstruction box = readLocal(redirect.enclosingElement); |
| 475 builder.add(new HFieldSet(redirect.name, box, value)); | 472 builder.add(new HFieldSet(redirect.name, box, value)); |
| 476 } else { | 473 } else { |
| 477 assert(isUsedInTry(element)); | 474 assert(isUsedInTry(element)); |
| 478 HParameterValue parameter = getActivationParameter(element); | 475 HInstruction instruction = getActivationValue(element); |
| 479 builder.add(new HFieldSet.fromActivation(parameter, value)); | 476 builder.add(new HFieldSet.fromActivation(instruction, value)); |
| 480 } | 477 } |
| 481 } | 478 } |
| 482 | 479 |
| 483 /** | 480 /** |
| 484 * This function must be called before visiting any children of the loop. In | 481 * This function must be called before visiting any children of the loop. In |
| 485 * particular it needs to be called before executing the initializers. | 482 * particular it needs to be called before executing the initializers. |
| 486 * | 483 * |
| 487 * The [LocalsHandler] will make the boxes and updates at the right moment. | 484 * The [LocalsHandler] will make the boxes and updates at the right moment. |
| 488 * The builder just needs to call [enterLoopBody] and [enterLoopUpdates] (for | 485 * The builder just needs to call [enterLoopBody] and [enterLoopUpdates] (for |
| 489 * [For] loops) at the correct places. For phi-handling [beginLoopHeader] and | 486 * [For] loops) at the correct places. For phi-handling [beginLoopHeader] and |
| (...skipping 2621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3111 visitSwitchCase(SwitchCase node) { | 3108 visitSwitchCase(SwitchCase node) { |
| 3112 compiler.internalError('SsaBuilder.visitSwitchCase'); | 3109 compiler.internalError('SsaBuilder.visitSwitchCase'); |
| 3113 } | 3110 } |
| 3114 | 3111 |
| 3115 visitCaseMatch(CaseMatch node) { | 3112 visitCaseMatch(CaseMatch node) { |
| 3116 compiler.internalError('SsaBuilder.visitCaseMatch'); | 3113 compiler.internalError('SsaBuilder.visitCaseMatch'); |
| 3117 } | 3114 } |
| 3118 | 3115 |
| 3119 visitTryStatement(TryStatement node) { | 3116 visitTryStatement(TryStatement node) { |
| 3120 work.allowSpeculativeOptimization = false; | 3117 work.allowSpeculativeOptimization = false; |
| 3118 // Save the current locals. The catch block, the finally block, and | |
| 3119 // the merge block need to use this state of the locals. | |
| 3120 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); | |
| 3121 | |
| 3121 HBasicBlock enterBlock = openNewBlock(); | 3122 HBasicBlock enterBlock = openNewBlock(); |
| 3122 HTry tryInstruction = new HTry(); | 3123 HTry tryInstruction = new HTry(); |
| 3123 List<HBasicBlock> blocks = <HBasicBlock>[]; | 3124 List<HBasicBlock> blocks = <HBasicBlock>[]; |
| 3124 blocks.add(close(tryInstruction)); | 3125 blocks.add(close(tryInstruction)); |
| 3125 | 3126 |
| 3126 HBasicBlock tryBody = graph.addNewBlock(); | 3127 HBasicBlock tryBody = graph.addNewBlock(); |
| 3127 enterBlock.addSuccessor(tryBody); | 3128 enterBlock.addSuccessor(tryBody); |
| 3128 open(tryBody); | 3129 open(tryBody); |
| 3129 visit(node.tryBlock); | 3130 visit(node.tryBlock); |
| 3130 if (!isAborted()) blocks.add(close(new HGoto())); | 3131 if (!isAborted()) blocks.add(close(new HGoto())); |
| 3131 SubGraph bodyGraph = new SubGraph(tryBody, lastOpenedBlock); | 3132 SubGraph bodyGraph = new SubGraph(tryBody, lastOpenedBlock); |
| 3132 SubGraph catchGraph = null; | 3133 SubGraph catchGraph = null; |
| 3133 HParameterValue exception = null; | 3134 HParameterValue exception = null; |
| 3134 if (!node.catchBlocks.isEmpty()) { | 3135 if (!node.catchBlocks.isEmpty()) { |
| 3136 localsHandler = new LocalsHandler.from(savedLocals); | |
|
floitsch
2012/05/29 18:31:38
Add comment:
The catch block must not reuse the ex
ngeoffray
2012/05/30 08:31:45
Done.
| |
| 3135 HBasicBlock block = graph.addNewBlock(); | 3137 HBasicBlock block = graph.addNewBlock(); |
| 3136 enterBlock.addSuccessor(block); | 3138 enterBlock.addSuccessor(block); |
| 3137 open(block); | 3139 open(block); |
| 3138 // Note that the name of this element is irrelevant. | 3140 // Note that the name of this element is irrelevant. |
| 3139 Element element = new Element( | 3141 Element element = new Element( |
| 3140 const SourceString('exception'), ElementKind.PARAMETER, work.element); | 3142 const SourceString('exception'), ElementKind.PARAMETER, work.element); |
| 3141 exception = new HParameterValue(element); | 3143 exception = new HParameterValue(element); |
| 3142 add(exception); | 3144 add(exception); |
| 3143 HInstruction oldRethrowableException = rethrowableException; | 3145 HInstruction oldRethrowableException = rethrowableException; |
| 3144 rethrowableException = exception; | 3146 rethrowableException = exception; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3192 visitThen, visitElse); | 3194 visitThen, visitElse); |
| 3193 } | 3195 } |
| 3194 } | 3196 } |
| 3195 | 3197 |
| 3196 CatchBlock firstBlock = link.head; | 3198 CatchBlock firstBlock = link.head; |
| 3197 handleIf(() { pushCondition(firstBlock); }, visitThen, visitElse); | 3199 handleIf(() { pushCondition(firstBlock); }, visitThen, visitElse); |
| 3198 if (!isAborted()) blocks.add(close(new HGoto())); | 3200 if (!isAborted()) blocks.add(close(new HGoto())); |
| 3199 | 3201 |
| 3200 rethrowableException = oldRethrowableException; | 3202 rethrowableException = oldRethrowableException; |
| 3201 catchGraph = new SubGraph(block, lastOpenedBlock); | 3203 catchGraph = new SubGraph(block, lastOpenedBlock); |
| 3204 tryInstruction.catchBlock = block; | |
| 3202 } | 3205 } |
| 3203 | 3206 |
| 3204 SubGraph finallyGraph = null; | 3207 SubGraph finallyGraph = null; |
| 3205 if (node.finallyBlock != null) { | 3208 if (node.finallyBlock != null) { |
| 3209 localsHandler = new LocalsHandler.from(savedLocals); | |
| 3206 HBasicBlock finallyBlock = graph.addNewBlock(); | 3210 HBasicBlock finallyBlock = graph.addNewBlock(); |
| 3207 enterBlock.addSuccessor(finallyBlock); | 3211 enterBlock.addSuccessor(finallyBlock); |
| 3208 open(finallyBlock); | 3212 open(finallyBlock); |
| 3209 visit(node.finallyBlock); | 3213 visit(node.finallyBlock); |
| 3210 if (!isAborted()) blocks.add(close(new HGoto())); | 3214 if (!isAborted()) blocks.add(close(new HGoto())); |
| 3211 tryInstruction.finallyBlock = finallyBlock; | 3215 tryInstruction.finallyBlock = finallyBlock; |
| 3212 finallyGraph = new SubGraph(finallyBlock, lastOpenedBlock); | 3216 finallyGraph = new SubGraph(finallyBlock, lastOpenedBlock); |
| 3213 } | 3217 } |
| 3214 | 3218 |
| 3215 HBasicBlock exitBlock = graph.addNewBlock(); | 3219 HBasicBlock exitBlock = graph.addNewBlock(); |
| 3216 | 3220 |
| 3217 for (HBasicBlock block in blocks) { | 3221 for (HBasicBlock block in blocks) { |
| 3218 block.addSuccessor(exitBlock); | 3222 block.addSuccessor(exitBlock); |
| 3219 } | 3223 } |
| 3220 | 3224 |
| 3221 open(exitBlock); | 3225 open(exitBlock); |
| 3226 localsHandler = savedLocals; | |
| 3227 | |
| 3222 enterBlock.setBlockFlow( | 3228 enterBlock.setBlockFlow( |
| 3223 new HTryBlockInformation( | 3229 new HTryBlockInformation( |
| 3224 wrapStatementGraph(bodyGraph), | 3230 wrapStatementGraph(bodyGraph), |
| 3225 exception, | 3231 exception, |
| 3226 wrapStatementGraph(catchGraph), | 3232 wrapStatementGraph(catchGraph), |
| 3227 wrapStatementGraph(finallyGraph)), | 3233 wrapStatementGraph(finallyGraph)), |
| 3228 exitBlock); | 3234 exitBlock); |
| 3229 } | 3235 } |
| 3230 | 3236 |
| 3231 visitScriptTag(ScriptTag node) { | 3237 visitScriptTag(ScriptTag node) { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3389 <HInstruction>[target, input], | 3395 <HInstruction>[target, input], |
| 3390 HType.STRING)); | 3396 HType.STRING)); |
| 3391 return builder.pop(); | 3397 return builder.pop(); |
| 3392 } | 3398 } |
| 3393 | 3399 |
| 3394 HInstruction result(Node node) { | 3400 HInstruction result(Node node) { |
| 3395 flushLiterals(node); | 3401 flushLiterals(node); |
| 3396 return prefix; | 3402 return prefix; |
| 3397 } | 3403 } |
| 3398 } | 3404 } |
| OLD | NEW |