| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 library tree_ir_builder; | 5 library tree_ir_builder; |
| 6 | 6 |
| 7 import '../dart2jslib.dart' as dart2js; | 7 import '../dart2jslib.dart' as dart2js; |
| 8 import '../dart_types.dart'; | 8 import '../dart_types.dart'; |
| 9 import '../elements/elements.dart'; | 9 import '../elements/elements.dart'; |
| 10 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; | 10 import '../cps_ir/cps_ir_nodes.dart' as cps_ir; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 Variable addMutableVariable(cps_ir.MutableVariable irVariable) { | 84 Variable addMutableVariable(cps_ir.MutableVariable irVariable) { |
| 85 if (irVariable.host != currentElement) { | 85 if (irVariable.host != currentElement) { |
| 86 return parent.addMutableVariable(irVariable); | 86 return parent.addMutableVariable(irVariable); |
| 87 } | 87 } |
| 88 assert(!local2mutable.containsKey(irVariable)); | 88 assert(!local2mutable.containsKey(irVariable)); |
| 89 Variable variable = new Variable(currentElement, irVariable.hint); | 89 Variable variable = new Variable(currentElement, irVariable.hint); |
| 90 local2mutable[irVariable] = variable; | 90 local2mutable[irVariable] = variable; |
| 91 return variable; | 91 return variable; |
| 92 } | 92 } |
| 93 | 93 |
| 94 Variable getMutableVariableReference( | 94 Variable getMutableVariable(cps_ir.MutableVariable mutableVariable) { |
| 95 if (mutableVariable.host != currentElement) { |
| 96 return parent.getMutableVariable(mutableVariable); |
| 97 } |
| 98 return local2mutable[mutableVariable]; |
| 99 } |
| 100 |
| 101 VariableUse getMutableVariableUse( |
| 95 cps_ir.Reference<cps_ir.MutableVariable> reference) { | 102 cps_ir.Reference<cps_ir.MutableVariable> reference) { |
| 96 if (reference.definition.host != currentElement) { | 103 Variable variable = getMutableVariable(reference.definition); |
| 97 return parent.getMutableVariableReference(reference); | 104 return new VariableUse(variable); |
| 98 } | |
| 99 Variable variable = local2mutable[reference.definition]; | |
| 100 ++variable.readCount; | |
| 101 return variable; | |
| 102 } | 105 } |
| 103 | 106 |
| 104 /// Obtains the variable representing the given primitive. Returns null for | 107 /// Obtains the variable representing the given primitive. Returns null for |
| 105 /// primitives that have no reference and do not need a variable. | 108 /// primitives that have no reference and do not need a variable. |
| 106 Variable getVariable(cps_ir.Primitive primitive) { | 109 Variable getVariable(cps_ir.Primitive primitive) { |
| 107 if (primitive.registerIndex == null) { | 110 if (primitive.registerIndex == null) { |
| 108 return null; // variable is unused | 111 return null; // variable is unused |
| 109 } | 112 } |
| 110 List<Variable> variables = local2variables.putIfAbsent(primitive.hint, | 113 List<Variable> variables = local2variables.putIfAbsent(primitive.hint, |
| 111 () => <Variable>[]); | 114 () => <Variable>[]); |
| 112 while (variables.length <= primitive.registerIndex) { | 115 while (variables.length <= primitive.registerIndex) { |
| 113 variables.add(new Variable(currentElement, primitive.hint)); | 116 variables.add(new Variable(currentElement, primitive.hint)); |
| 114 } | 117 } |
| 115 return variables[primitive.registerIndex]; | 118 return variables[primitive.registerIndex]; |
| 116 } | 119 } |
| 117 | 120 |
| 118 /// Obtains a reference to the tree Variable corresponding to the IR primitive | 121 /// Obtains a reference to the tree Variable corresponding to the IR primitive |
| 119 /// referred to by [reference]. | 122 /// referred to by [reference]. |
| 120 /// This increments the reference count for the given variable, so the | 123 /// This increments the reference count for the given variable, so the |
| 121 /// returned expression must be used in the tree. | 124 /// returned expression must be used in the tree. |
| 122 Expression getVariableReference(cps_ir.Reference reference) { | 125 VariableUse getVariableUse(cps_ir.Reference<cps_ir.Primitive> reference) { |
| 123 Variable variable = getVariable(reference.definition); | 126 Variable variable = getVariable(reference.definition); |
| 124 if (variable == null) { | 127 if (variable == null) { |
| 125 internalError( | 128 internalError( |
| 126 CURRENT_ELEMENT_SPANNABLE, | 129 CURRENT_ELEMENT_SPANNABLE, |
| 127 "Reference to ${reference.definition} has no register"); | 130 "Reference to ${reference.definition} has no register"); |
| 128 } | 131 } |
| 129 ++variable.readCount; | 132 return new VariableUse(variable); |
| 130 return variable; | |
| 131 } | 133 } |
| 132 | 134 |
| 133 ExecutableDefinition build(cps_ir.ExecutableDefinition node) { | 135 ExecutableDefinition build(cps_ir.ExecutableDefinition node) { |
| 134 if (node is cps_ir.FieldDefinition) { | 136 if (node is cps_ir.FieldDefinition) { |
| 135 return buildField(node); | 137 return buildField(node); |
| 136 } else if (node is cps_ir.ConstructorDefinition) { | 138 } else if (node is cps_ir.ConstructorDefinition) { |
| 137 return buildConstructor(node); | 139 return buildConstructor(node); |
| 138 } else { | 140 } else { |
| 139 assert(dart2js.invariant( | 141 assert(dart2js.invariant( |
| 140 CURRENT_ELEMENT_SPANNABLE, | 142 CURRENT_ELEMENT_SPANNABLE, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 161 Variable addFunctionParameter(cps_ir.Definition variable) { | 163 Variable addFunctionParameter(cps_ir.Definition variable) { |
| 162 if (variable is cps_ir.Parameter) { | 164 if (variable is cps_ir.Parameter) { |
| 163 return getVariable(variable); | 165 return getVariable(variable); |
| 164 } else { | 166 } else { |
| 165 return addMutableVariable(variable as cps_ir.MutableVariable); | 167 return addMutableVariable(variable as cps_ir.MutableVariable); |
| 166 } | 168 } |
| 167 } | 169 } |
| 168 | 170 |
| 169 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { | 171 FunctionDefinition buildFunction(cps_ir.FunctionDefinition node) { |
| 170 currentElement = node.element; | 172 currentElement = node.element; |
| 171 List<Variable> parameters = <Variable>[]; | 173 List<Variable> parameters = |
| 172 for (cps_ir.Definition p in node.parameters) { | 174 node.parameters.map(addFunctionParameter).toList(); |
| 173 Variable parameter = addFunctionParameter(p); | |
| 174 assert(parameter != null); | |
| 175 ++parameter.writeCount; // Being a parameter counts as a write. | |
| 176 parameters.add(parameter); | |
| 177 } | |
| 178 | |
| 179 Statement body; | 175 Statement body; |
| 180 if (!node.isAbstract) { | 176 if (!node.isAbstract) { |
| 181 returnContinuation = node.body.returnContinuation; | 177 returnContinuation = node.body.returnContinuation; |
| 182 phiTempVar = new Variable(node.element, null); | 178 phiTempVar = new Variable(node.element, null); |
| 183 body = visit(node.body); | 179 body = visit(node.body); |
| 184 } | 180 } |
| 185 | 181 |
| 186 return new FunctionDefinition(node.element, parameters, | 182 return new FunctionDefinition(node.element, parameters, |
| 187 body, node.localConstants, node.defaultParameterValues); | 183 body, node.localConstants, node.defaultParameterValues); |
| 188 } | 184 } |
| 189 | 185 |
| 190 ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) { | 186 ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) { |
| 191 currentElement = node.element; | 187 currentElement = node.element; |
| 192 List<Variable> parameters = <Variable>[]; | 188 List<Variable> parameters = |
| 193 for (cps_ir.Definition p in node.parameters) { | 189 node.parameters.map(addFunctionParameter).toList(); |
| 194 Variable parameter = addFunctionParameter(p); | |
| 195 assert(parameter != null); | |
| 196 ++parameter.writeCount; // Being a parameter counts as a write. | |
| 197 parameters.add(parameter); | |
| 198 } | |
| 199 List<Initializer> initializers; | 190 List<Initializer> initializers; |
| 200 Statement body; | 191 Statement body; |
| 201 if (!node.isAbstract) { | 192 if (!node.isAbstract) { |
| 202 initializers = node.initializers.map(visit).toList(); | 193 initializers = node.initializers.map(visit).toList(); |
| 203 returnContinuation = node.body.returnContinuation; | 194 returnContinuation = node.body.returnContinuation; |
| 204 | 195 |
| 205 phiTempVar = new Variable(node.element, null); | 196 phiTempVar = new Variable(node.element, null); |
| 206 body = visit(node.body); | 197 body = visit(node.body); |
| 207 } | 198 } |
| 208 | 199 |
| 209 return new ConstructorDefinition(node.element, parameters, | 200 return new ConstructorDefinition(node.element, parameters, |
| 210 body, initializers, node.localConstants, node.defaultParameterValues); | 201 body, initializers, node.localConstants, node.defaultParameterValues); |
| 211 } | 202 } |
| 212 | 203 |
| 213 /// Returns a list of variables corresponding to the arguments to a method | 204 /// Returns a list of variables corresponding to the arguments to a method |
| 214 /// call or similar construct. | 205 /// call or similar construct. |
| 215 /// | 206 /// |
| 216 /// The `readCount` for these variables will be incremented. | 207 /// The `readCount` for these variables will be incremented. |
| 217 /// | 208 /// |
| 218 /// The list will be typed as a list of [Expression] to allow inplace updates | 209 /// The list will be typed as a list of [Expression] to allow inplace updates |
| 219 /// on the list during the rewrite phases. | 210 /// on the list during the rewrite phases. |
| 220 List<Expression> translateArguments(List<cps_ir.Reference> args) { | 211 List<Expression> translateArguments(List<cps_ir.Reference> args) { |
| 221 return new List<Expression>.generate(args.length, | 212 return new List<Expression>.generate(args.length, |
| 222 (int index) => getVariableReference(args[index]), | 213 (int index) => getVariableUse(args[index]), |
| 223 growable: false); | 214 growable: false); |
| 224 } | 215 } |
| 225 | 216 |
| 226 /// Returns the list of variables corresponding to the arguments to a join | 217 /// Returns the list of variables corresponding to the arguments to a join |
| 227 /// continuation. | 218 /// continuation. |
| 228 /// | 219 /// |
| 229 /// The `readCount` of these variables will not be incremented. Instead, | 220 /// The `readCount` of these variables will not be incremented. Instead, |
| 230 /// [buildPhiAssignments] will handle the increment, if necessary. | 221 /// [buildPhiAssignments] will handle the increment, if necessary. |
| 231 List<Variable> translatePhiArguments(List<cps_ir.Reference> args) { | 222 List<Variable> translatePhiArguments(List<cps_ir.Reference> args) { |
| 232 return new List<Variable>.generate(args.length, | 223 return new List<Variable>.generate(args.length, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 } | 264 } |
| 274 List<int> list = rightHand[arg]; | 265 List<int> list = rightHand[arg]; |
| 275 if (list == null) { | 266 if (list == null) { |
| 276 rightHand[arg] = list = <int>[]; | 267 rightHand[arg] = list = <int>[]; |
| 277 } | 268 } |
| 278 list.add(i); | 269 list.add(i); |
| 279 } | 270 } |
| 280 | 271 |
| 281 Statement first, current; | 272 Statement first, current; |
| 282 void addAssignment(Variable dst, Variable src) { | 273 void addAssignment(Variable dst, Variable src) { |
| 283 ++src.readCount; | |
| 284 // `dst.writeCount` will be updated by the Assign constructor. | |
| 285 if (first == null) { | 274 if (first == null) { |
| 286 first = current = new Assign(dst, src, null); | 275 first = current = new Assign(dst, new VariableUse(src), null); |
| 287 } else { | 276 } else { |
| 288 current = current.next = new Assign(dst, src, null); | 277 current = current.next = new Assign(dst, new VariableUse(src), null); |
| 289 } | 278 } |
| 290 } | 279 } |
| 291 | 280 |
| 292 List<Variable> assignmentSrc = new List<Variable>(parameters.length); | 281 List<Variable> assignmentSrc = new List<Variable>(parameters.length); |
| 293 List<bool> done = new List<bool>(parameters.length); | 282 List<bool> done = new List<bool>(parameters.length); |
| 294 void visitAssignment(int i) { | 283 void visitAssignment(int i) { |
| 295 if (done[i] == true) { | 284 if (done[i] == true) { |
| 296 return; | 285 return; |
| 297 } | 286 } |
| 298 Variable param = getVariable(parameters[i]); | 287 Variable param = getVariable(parameters[i]); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 } | 415 } |
| 427 | 416 |
| 428 Statement visitInvokeStatic(cps_ir.InvokeStatic node) { | 417 Statement visitInvokeStatic(cps_ir.InvokeStatic node) { |
| 429 // Calls are translated to direct style. | 418 // Calls are translated to direct style. |
| 430 List<Expression> arguments = translateArguments(node.arguments); | 419 List<Expression> arguments = translateArguments(node.arguments); |
| 431 Expression invoke = new InvokeStatic(node.target, node.selector, arguments); | 420 Expression invoke = new InvokeStatic(node.target, node.selector, arguments); |
| 432 return continueWithExpression(node.continuation, invoke); | 421 return continueWithExpression(node.continuation, invoke); |
| 433 } | 422 } |
| 434 | 423 |
| 435 Statement visitInvokeMethod(cps_ir.InvokeMethod node) { | 424 Statement visitInvokeMethod(cps_ir.InvokeMethod node) { |
| 436 Expression invoke = new InvokeMethod(getVariableReference(node.receiver), | 425 Expression invoke = new InvokeMethod(getVariableUse(node.receiver), |
| 437 node.selector, | 426 node.selector, |
| 438 translateArguments(node.arguments)); | 427 translateArguments(node.arguments)); |
| 439 return continueWithExpression(node.continuation, invoke); | 428 return continueWithExpression(node.continuation, invoke); |
| 440 } | 429 } |
| 441 | 430 |
| 442 Statement visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) { | 431 Statement visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) { |
| 443 Expression receiver = getVariableReference(node.receiver); | 432 Expression receiver = getVariableUse(node.receiver); |
| 444 List<Expression> arguments = translateArguments(node.arguments); | 433 List<Expression> arguments = translateArguments(node.arguments); |
| 445 Expression invoke = new InvokeMethodDirectly(receiver, node.target, | 434 Expression invoke = new InvokeMethodDirectly(receiver, node.target, |
| 446 node.selector, arguments); | 435 node.selector, arguments); |
| 447 return continueWithExpression(node.continuation, invoke); | 436 return continueWithExpression(node.continuation, invoke); |
| 448 } | 437 } |
| 449 | 438 |
| 450 Statement visitConcatenateStrings(cps_ir.ConcatenateStrings node) { | 439 Statement visitConcatenateStrings(cps_ir.ConcatenateStrings node) { |
| 451 List<Expression> arguments = translateArguments(node.arguments); | 440 List<Expression> arguments = translateArguments(node.arguments); |
| 452 Expression concat = new ConcatenateStrings(arguments); | 441 Expression concat = new ConcatenateStrings(arguments); |
| 453 return continueWithExpression(node.continuation, concat); | 442 return continueWithExpression(node.continuation, concat); |
| 454 } | 443 } |
| 455 | 444 |
| 456 Statement continueWithExpression(cps_ir.Reference continuation, | 445 Statement continueWithExpression(cps_ir.Reference continuation, |
| 457 Expression expression) { | 446 Expression expression) { |
| 458 cps_ir.Continuation cont = continuation.definition; | 447 cps_ir.Continuation cont = continuation.definition; |
| 459 if (cont == returnContinuation) { | 448 if (cont == returnContinuation) { |
| 460 return new Return(expression); | 449 return new Return(expression); |
| 461 } else { | 450 } else { |
| 462 assert(cont.parameters.length == 1); | 451 assert(cont.parameters.length == 1); |
| 463 Function nextBuilder = cont.hasExactlyOneUse ? | 452 Function nextBuilder = cont.hasExactlyOneUse ? |
| 464 () => visit(cont.body) : () => new Break(labels[cont]); | 453 () => visit(cont.body) : () => new Break(labels[cont]); |
| 465 return buildContinuationAssignment(cont.parameters.single, expression, | 454 return buildContinuationAssignment(cont.parameters.single, expression, |
| 466 nextBuilder); | 455 nextBuilder); |
| 467 } | 456 } |
| 468 } | 457 } |
| 469 | 458 |
| 470 Statement visitLetMutable(cps_ir.LetMutable node) { | 459 Statement visitLetMutable(cps_ir.LetMutable node) { |
| 471 Variable variable = addMutableVariable(node.variable); | 460 Variable variable = addMutableVariable(node.variable); |
| 472 Expression value = getVariableReference(node.value); | 461 Expression value = getVariableUse(node.value); |
| 473 return new Assign(variable, value, visit(node.body), isDeclaration: true); | 462 return new Assign(variable, value, visit(node.body), isDeclaration: true); |
| 474 } | 463 } |
| 475 | 464 |
| 476 Expression visitGetMutableVariable(cps_ir.GetMutableVariable node) { | 465 Expression visitGetMutableVariable(cps_ir.GetMutableVariable node) { |
| 477 return getMutableVariableReference(node.variable); | 466 return getMutableVariableUse(node.variable); |
| 478 } | 467 } |
| 479 | 468 |
| 480 Statement visitSetMutableVariable(cps_ir.SetMutableVariable node) { | 469 Statement visitSetMutableVariable(cps_ir.SetMutableVariable node) { |
| 481 Variable variable = getMutableVariableReference(node.variable); | 470 Variable variable = getMutableVariable(node.variable.definition); |
| 482 Expression value = getVariableReference(node.value); | 471 Expression value = getVariableUse(node.value); |
| 483 return new Assign(variable, value, visit(node.body)); | 472 return new Assign(variable, value, visit(node.body)); |
| 484 } | 473 } |
| 485 | 474 |
| 486 Statement visitDeclareFunction(cps_ir.DeclareFunction node) { | 475 Statement visitDeclareFunction(cps_ir.DeclareFunction node) { |
| 487 Variable variable = addMutableVariable(node.variable); | 476 Variable variable = addMutableVariable(node.variable); |
| 488 FunctionDefinition function = makeSubFunction(node.definition); | 477 FunctionDefinition function = makeSubFunction(node.definition); |
| 489 return new FunctionDeclaration(variable, function, visit(node.body)); | 478 return new FunctionDeclaration(variable, function, visit(node.body)); |
| 490 } | 479 } |
| 491 | 480 |
| 492 Statement visitTypeOperator(cps_ir.TypeOperator node) { | 481 Statement visitTypeOperator(cps_ir.TypeOperator node) { |
| 493 Expression receiver = getVariableReference(node.receiver); | 482 Expression receiver = getVariableUse(node.receiver); |
| 494 Expression concat = | 483 Expression concat = |
| 495 new TypeOperator(receiver, node.type, isTypeTest: node.isTypeTest); | 484 new TypeOperator(receiver, node.type, isTypeTest: node.isTypeTest); |
| 496 return continueWithExpression(node.continuation, concat); | 485 return continueWithExpression(node.continuation, concat); |
| 497 } | 486 } |
| 498 | 487 |
| 499 Statement visitInvokeConstructor(cps_ir.InvokeConstructor node) { | 488 Statement visitInvokeConstructor(cps_ir.InvokeConstructor node) { |
| 500 List<Expression> arguments = translateArguments(node.arguments); | 489 List<Expression> arguments = translateArguments(node.arguments); |
| 501 Expression invoke = | 490 Expression invoke = |
| 502 new InvokeConstructor(node.type, node.target, node.selector, arguments); | 491 new InvokeConstructor(node.type, node.target, node.selector, arguments); |
| 503 return continueWithExpression(node.continuation, invoke); | 492 return continueWithExpression(node.continuation, invoke); |
| 504 } | 493 } |
| 505 | 494 |
| 506 Statement visitInvokeContinuation(cps_ir.InvokeContinuation node) { | 495 Statement visitInvokeContinuation(cps_ir.InvokeContinuation node) { |
| 507 // Invocations of the return continuation are translated to returns. | 496 // Invocations of the return continuation are translated to returns. |
| 508 // Other continuation invocations are replaced with assignments of the | 497 // Other continuation invocations are replaced with assignments of the |
| 509 // arguments to formal parameter variables, followed by the body if | 498 // arguments to formal parameter variables, followed by the body if |
| 510 // the continuation is singly reference or a break if it is multiply | 499 // the continuation is singly reference or a break if it is multiply |
| 511 // referenced. | 500 // referenced. |
| 512 cps_ir.Continuation cont = node.continuation.definition; | 501 cps_ir.Continuation cont = node.continuation.definition; |
| 513 if (cont == returnContinuation) { | 502 if (cont == returnContinuation) { |
| 514 assert(node.arguments.length == 1); | 503 assert(node.arguments.length == 1); |
| 515 return new Return(getVariableReference(node.arguments.single)); | 504 return new Return(getVariableUse(node.arguments.single)); |
| 516 } else { | 505 } else { |
| 517 List<Expression> arguments = translatePhiArguments(node.arguments); | 506 List<Variable> arguments = translatePhiArguments(node.arguments); |
| 518 return buildPhiAssignments(cont.parameters, arguments, | 507 return buildPhiAssignments(cont.parameters, arguments, |
| 519 () { | 508 () { |
| 520 // Translate invocations of recursive and non-recursive | 509 // Translate invocations of recursive and non-recursive |
| 521 // continuations differently. | 510 // continuations differently. |
| 522 // * Non-recursive continuations | 511 // * Non-recursive continuations |
| 523 // - If there is one use, translate the continuation body | 512 // - If there is one use, translate the continuation body |
| 524 // inline at the invocation site. | 513 // inline at the invocation site. |
| 525 // - If there are multiple uses, translate to Break. | 514 // - If there are multiple uses, translate to Break. |
| 526 // * Recursive continuations | 515 // * Recursive continuations |
| 527 // - There is a single non-recursive invocation. Translate | 516 // - There is a single non-recursive invocation. Translate |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 575 return new LiteralList( | 564 return new LiteralList( |
| 576 node.type, | 565 node.type, |
| 577 translateArguments(node.values)); | 566 translateArguments(node.values)); |
| 578 } | 567 } |
| 579 | 568 |
| 580 Expression visitLiteralMap(cps_ir.LiteralMap node) { | 569 Expression visitLiteralMap(cps_ir.LiteralMap node) { |
| 581 return new LiteralMap( | 570 return new LiteralMap( |
| 582 node.type, | 571 node.type, |
| 583 new List<LiteralMapEntry>.generate(node.entries.length, (int index) { | 572 new List<LiteralMapEntry>.generate(node.entries.length, (int index) { |
| 584 return new LiteralMapEntry( | 573 return new LiteralMapEntry( |
| 585 getVariableReference(node.entries[index].key), | 574 getVariableUse(node.entries[index].key), |
| 586 getVariableReference(node.entries[index].value)); | 575 getVariableUse(node.entries[index].value)); |
| 587 }) | 576 }) |
| 588 ); | 577 ); |
| 589 } | 578 } |
| 590 | 579 |
| 591 FunctionDefinition makeSubFunction(cps_ir.FunctionDefinition function) { | 580 FunctionDefinition makeSubFunction(cps_ir.FunctionDefinition function) { |
| 592 return createInnerBuilder().buildFunction(function); | 581 return createInnerBuilder().buildFunction(function); |
| 593 } | 582 } |
| 594 | 583 |
| 595 Node visitCreateFunction(cps_ir.CreateFunction node) { | 584 Node visitCreateFunction(cps_ir.CreateFunction node) { |
| 596 FunctionDefinition def = makeSubFunction(node.definition); | 585 FunctionDefinition def = makeSubFunction(node.definition); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 613 } | 602 } |
| 614 | 603 |
| 615 Expression visitContinuation(cps_ir.Continuation node) { | 604 Expression visitContinuation(cps_ir.Continuation node) { |
| 616 // Until continuations with multiple uses are supported, they are not | 605 // Until continuations with multiple uses are supported, they are not |
| 617 // visited. | 606 // visited. |
| 618 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.'); | 607 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.'); |
| 619 return null; | 608 return null; |
| 620 } | 609 } |
| 621 | 610 |
| 622 Expression visitIsTrue(cps_ir.IsTrue node) { | 611 Expression visitIsTrue(cps_ir.IsTrue node) { |
| 623 return getVariableReference(node.value); | 612 return getVariableUse(node.value); |
| 624 } | 613 } |
| 625 } | 614 } |
| 626 | 615 |
| OLD | NEW |