| 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 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 // accessed through a closure-field. | 410 // accessed through a closure-field. |
| 411 // Calling [readLocal] makes sure we generate the correct code to get | 411 // Calling [readLocal] makes sure we generate the correct code to get |
| 412 // the box. | 412 // the box. |
| 413 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); | 413 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); |
| 414 HInstruction box = readLocal(redirect.enclosingElement); | 414 HInstruction box = readLocal(redirect.enclosingElement); |
| 415 HInstruction lookup = new HFieldGet(redirect, box); | 415 HInstruction lookup = new HFieldGet(redirect, box); |
| 416 builder.add(lookup); | 416 builder.add(lookup); |
| 417 return lookup; | 417 return lookup; |
| 418 } else { | 418 } else { |
| 419 assert(isUsedInTry(element)); | 419 assert(isUsedInTry(element)); |
| 420 HParameterValue parameter = getActivationParameter(element); | 420 HLocalValue local = getLocal(element); |
| 421 HInstruction variable = new HFieldGet.fromActivation(parameter); | 421 HInstruction variable = new HLocalGet(element, local); |
| 422 builder.add(variable); | 422 builder.add(variable); |
| 423 return variable; | 423 return variable; |
| 424 } | 424 } |
| 425 } | 425 } |
| 426 | 426 |
| 427 HType cachedTypeOfThis; | 427 HType cachedTypeOfThis; |
| 428 | 428 |
| 429 HInstruction readThis() { | 429 HInstruction readThis() { |
| 430 HInstruction res = readLocal(closureData.thisElement); | 430 HInstruction res = readLocal(closureData.thisElement); |
| 431 if (res.guaranteedType === null) { | 431 if (res.guaranteedType === null) { |
| 432 if (cachedTypeOfThis === null) { | 432 if (cachedTypeOfThis === null) { |
| 433 assert(closureData.isClosure()); | 433 assert(closureData.isClosure()); |
| 434 Element element = closureData.thisElement; | 434 Element element = closureData.thisElement; |
| 435 ClassElement cls = element.enclosingElement.enclosingElement; | 435 ClassElement cls = element.enclosingElement.enclosingElement; |
| 436 Type type = cls.computeType(builder.compiler); | 436 Type type = cls.computeType(builder.compiler); |
| 437 cachedTypeOfThis = new HBoundedType.nonNull(type); | 437 cachedTypeOfThis = new HBoundedType.nonNull(type); |
| 438 } | 438 } |
| 439 res.guaranteedType = cachedTypeOfThis; | 439 res.guaranteedType = cachedTypeOfThis; |
| 440 } | 440 } |
| 441 return res; | 441 return res; |
| 442 } | 442 } |
| 443 | 443 |
| 444 HParameterValue getActivationParameter(Element element) { | 444 HLocalValue getLocal(Element element) { |
| 445 // If the element is a parameter, we already have a | 445 // If the element is a parameter, we already have a |
| 446 // HParameterValue for it. We cannot create another one because | 446 // HParameterValue for it. We cannot create another one because |
| 447 // it could then have another name than the real parameter. And | 447 // it could then have another name than the real parameter. And |
| 448 // the other one would not know it is just a copy of the real | 448 // the other one would not know it is just a copy of the real |
| 449 // parameter. | 449 // parameter. |
| 450 if (element.isParameter()) return builder.parameters[element]; | 450 if (element.isParameter()) return builder.parameters[element]; |
| 451 | 451 |
| 452 return builder.activationVariables.putIfAbsent(element, () { | 452 return builder.activationVariables.putIfAbsent(element, () { |
| 453 HParameterValue parameter = new HParameterValue(element); | 453 HLocalValue local = new HLocalValue(element); |
| 454 builder.graph.entry.addAtExit(parameter); | 454 builder.graph.entry.addAtExit(local); |
| 455 return parameter; | 455 return local; |
| 456 }); | 456 }); |
| 457 } | 457 } |
| 458 | 458 |
| 459 /** | 459 /** |
| 460 * Sets the [element] to [value]. If the element is boxed or stored in a | 460 * Sets the [element] to [value]. If the element is boxed or stored in a |
| 461 * closure then the method generates code to set the value. | 461 * closure then the method generates code to set the value. |
| 462 */ | 462 */ |
| 463 void updateLocal(Element element, HInstruction value) { | 463 void updateLocal(Element element, HInstruction value) { |
| 464 assert(!isStoredInClosureField(element)); | 464 assert(!isStoredInClosureField(element)); |
| 465 if (isAccessedDirectly(element)) { | 465 if (isAccessedDirectly(element)) { |
| 466 directLocals[element] = value; | 466 directLocals[element] = value; |
| 467 } else if (isBoxed(element)) { | 467 } else if (isBoxed(element)) { |
| 468 Element redirect = redirectionMapping[element]; | 468 Element redirect = redirectionMapping[element]; |
| 469 // The box itself could be captured, or be local. A local variable that | 469 // 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. | 470 // 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 | 471 // Inside the closure the box is stored in a closure-field and cannot |
| 472 // be accessed directly. | 472 // be accessed directly. |
| 473 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); | 473 assert(redirect.enclosingElement.kind == ElementKind.VARIABLE); |
| 474 HInstruction box = readLocal(redirect.enclosingElement); | 474 HInstruction box = readLocal(redirect.enclosingElement); |
| 475 builder.add(new HFieldSet(redirect, box, value)); | 475 builder.add(new HFieldSet(redirect, box, value)); |
| 476 } else { | 476 } else { |
| 477 assert(isUsedInTry(element)); | 477 assert(isUsedInTry(element)); |
| 478 HParameterValue parameter = getActivationParameter(element); | 478 HLocalValue local = getLocal(element); |
| 479 builder.add(new HFieldSet.fromActivation(parameter, value)); | 479 builder.add(new HLocalSet(element, local, value)); |
| 480 } | 480 } |
| 481 } | 481 } |
| 482 | 482 |
| 483 /** | 483 /** |
| 484 * This function must be called before visiting any children of the loop. In | 484 * This function must be called before visiting any children of the loop. In |
| 485 * particular it needs to be called before executing the initializers. | 485 * particular it needs to be called before executing the initializers. |
| 486 * | 486 * |
| 487 * The [LocalsHandler] will make the boxes and updates at the right moment. | 487 * The [LocalsHandler] will make the boxes and updates at the right moment. |
| 488 * The builder just needs to call [enterLoopBody] and [enterLoopUpdates] (for | 488 * The builder just needs to call [enterLoopBody] and [enterLoopUpdates] (for |
| 489 * [For] loops) at the correct places. For phi-handling [beginLoopHeader] and | 489 * [For] loops) at the correct places. For phi-handling [beginLoopHeader] and |
| (...skipping 2972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3462 void visitNodeList(NodeList node) { | 3462 void visitNodeList(NodeList node) { |
| 3463 node.visitChildren(this); | 3463 node.visitChildren(this); |
| 3464 } | 3464 } |
| 3465 | 3465 |
| 3466 HInstruction concat(HInstruction left, HInstruction right) { | 3466 HInstruction concat(HInstruction left, HInstruction right) { |
| 3467 HInstruction instruction = new HStringConcat(left, right, diagnosticNode); | 3467 HInstruction instruction = new HStringConcat(left, right, diagnosticNode); |
| 3468 builder.add(instruction); | 3468 builder.add(instruction); |
| 3469 return instruction; | 3469 return instruction; |
| 3470 } | 3470 } |
| 3471 } | 3471 } |
| OLD | NEW |