| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 dart2js.ir_builder; | 5 library dart2js.ir_builder; |
| 6 | 6 |
| 7 import '../constants/expressions.dart'; | 7 import '../constants/expressions.dart'; |
| 8 import '../constants/values.dart' show PrimitiveConstantValue; | 8 import '../constants/values.dart' show PrimitiveConstantValue; |
| 9 import '../dart_backend/dart_backend.dart' show DartBackend; | 9 import '../dart_backend/dart_backend.dart' show DartBackend; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 ir.InvokeContinuation invoke = new ir.InvokeContinuation.uninitialized(); | 120 ir.InvokeContinuation invoke = new ir.InvokeContinuation.uninitialized(); |
| 121 builder.add(invoke); | 121 builder.add(invoke); |
| 122 _invocations.add(invoke); | 122 _invocations.add(invoke); |
| 123 _environments.add(builder.environment); | 123 _environments.add(builder.environment); |
| 124 builder._current = null; | 124 builder._current = null; |
| 125 // TODO(kmillikin): Can we set builder.environment to null to make it | 125 // TODO(kmillikin): Can we set builder.environment to null to make it |
| 126 // less likely to mutate it? | 126 // less likely to mutate it? |
| 127 } | 127 } |
| 128 } | 128 } |
| 129 | 129 |
| 130 /// Mixin that provided encapsulated access to nested builders. | 130 /// Function for building nodes in the context of the provided [builder]. |
| 131 class IrBuilderMixin { | 131 typedef ir.Node SubbuildFunction(IrBuilder builder); |
| 132 |
| 133 /// Mixin that provides encapsulated access to nested builders. |
| 134 abstract class IrBuilderMixin<N> { |
| 132 IrBuilder _irBuilder; | 135 IrBuilder _irBuilder; |
| 133 | 136 |
| 134 /// Execute [f] with [builder] as the current builder. | 137 /// Execute [f] with [builder] as the current builder. |
| 135 withBuilder(IrBuilder builder, f()) { | 138 withBuilder(IrBuilder builder, f()) { |
| 136 assert(builder != null); | 139 assert(builder != null); |
| 137 IrBuilder prev = _irBuilder; | 140 IrBuilder prev = _irBuilder; |
| 138 _irBuilder = builder; | 141 _irBuilder = builder; |
| 139 var result = f(); | 142 var result = f(); |
| 140 _irBuilder = prev; | 143 _irBuilder = prev; |
| 141 return result; | 144 return result; |
| 142 } | 145 } |
| 143 | 146 |
| 144 /// The current builder. | 147 /// The current builder. |
| 145 IrBuilder get irBuilder { | 148 IrBuilder get irBuilder { |
| 146 assert(_irBuilder != null); | 149 assert(_irBuilder != null); |
| 147 return _irBuilder; | 150 return _irBuilder; |
| 148 } | 151 } |
| 152 |
| 153 /// Visits the [node]. |
| 154 ir.Primitive visit(N node); |
| 155 |
| 156 /// Builds and returns the [ir.Node] for [node] or returns `null` if |
| 157 /// [node] is `null`. |
| 158 ir.Node build(N node) => node != null ? visit(node) : null; |
| 159 |
| 160 /// Returns a closure that takes an [IrBuilder] and builds [node] in its |
| 161 /// context using [build]. |
| 162 SubbuildFunction subbuild(N node) { |
| 163 return (IrBuilder builder) => withBuilder(builder, () => build(node)); |
| 164 } |
| 149 } | 165 } |
| 150 | 166 |
| 151 | |
| 152 /// Shared state between nested builders. | 167 /// Shared state between nested builders. |
| 153 class IrBuilderSharedState { | 168 class IrBuilderSharedState { |
| 154 final ConstantSystem constantSystem; | 169 final ConstantSystem constantSystem; |
| 155 | 170 |
| 156 /// A stack of collectors for breaks. | 171 /// A stack of collectors for breaks. |
| 157 final List<JumpCollector> breakCollectors = <JumpCollector>[]; | 172 final List<JumpCollector> breakCollectors = <JumpCollector>[]; |
| 158 | 173 |
| 159 /// A stack of collectors for continues. | 174 /// A stack of collectors for continues. |
| 160 final List<JumpCollector> continueCollectors = <JumpCollector>[]; | 175 final List<JumpCollector> continueCollectors = <JumpCollector>[]; |
| 161 | 176 |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 ir.Constant buildNullLiteral() { | 363 ir.Constant buildNullLiteral() { |
| 349 return _buildPrimitiveConstant(state.constantSystem.createNull()); | 364 return _buildPrimitiveConstant(state.constantSystem.createNull()); |
| 350 } | 365 } |
| 351 | 366 |
| 352 /// Create a string literal. | 367 /// Create a string literal. |
| 353 ir.Constant buildStringLiteral(String value) { | 368 ir.Constant buildStringLiteral(String value) { |
| 354 return _buildPrimitiveConstant( | 369 return _buildPrimitiveConstant( |
| 355 state.constantSystem.createString(new ast.DartString.literal(value))); | 370 state.constantSystem.createString(new ast.DartString.literal(value))); |
| 356 } | 371 } |
| 357 | 372 |
| 373 /// Creates a conditional expression with the provided [condition] where the |
| 374 /// then and else expression are created through the [buildThenExpression] and |
| 375 /// [buildElseExpression] functions, respectively. |
| 376 ir.Primitive buildConditional( |
| 377 ir.Primitive condition, |
| 378 ir.Primitive buildThenExpression(IrBuilder builder), |
| 379 ir.Primitive buildElseExpression(IrBuilder builder)) { |
| 380 |
| 381 assert(isOpen); |
| 382 |
| 383 // The then and else expressions are delimited. |
| 384 IrBuilder thenBuilder = new IrBuilder.delimited(this); |
| 385 IrBuilder elseBuilder = new IrBuilder.delimited(this); |
| 386 ir.Primitive thenValue = buildThenExpression(thenBuilder); |
| 387 ir.Primitive elseValue = buildElseExpression(elseBuilder); |
| 388 |
| 389 // Treat the values of the subexpressions as named values in the |
| 390 // environment, so they will be treated as arguments to the join-point |
| 391 // continuation. |
| 392 assert(environment.length == thenBuilder.environment.length); |
| 393 assert(environment.length == elseBuilder.environment.length); |
| 394 thenBuilder.environment.extend(null, thenValue); |
| 395 elseBuilder.environment.extend(null, elseValue); |
| 396 JumpCollector jumps = new JumpCollector(null); |
| 397 jumps.addJump(thenBuilder); |
| 398 jumps.addJump(elseBuilder); |
| 399 ir.Continuation joinContinuation = |
| 400 createJoin(environment.length + 1, jumps); |
| 401 |
| 402 // Build the term |
| 403 // let cont join(x, ..., result) = [] in |
| 404 // let cont then() = [[thenPart]]; join(v, ...) in |
| 405 // let cont else() = [[elsePart]]; join(v, ...) in |
| 406 // if condition (then, else) |
| 407 ir.Continuation thenContinuation = new ir.Continuation([]); |
| 408 ir.Continuation elseContinuation = new ir.Continuation([]); |
| 409 thenContinuation.body = thenBuilder._root; |
| 410 elseContinuation.body = elseBuilder._root; |
| 411 add(new ir.LetCont(joinContinuation, |
| 412 new ir.LetCont(thenContinuation, |
| 413 new ir.LetCont(elseContinuation, |
| 414 new ir.Branch(new ir.IsTrue(condition), |
| 415 thenContinuation, |
| 416 elseContinuation))))); |
| 417 return (thenValue == elseValue) |
| 418 ? thenValue |
| 419 : joinContinuation.parameters.last; |
| 420 |
| 421 } |
| 422 |
| 358 /// Create a get access of [local]. | 423 /// Create a get access of [local]. |
| 359 ir.Primitive buildLocalGet(Element local) { | 424 ir.Primitive buildLocalGet(Element local) { |
| 360 assert(isOpen); | 425 assert(isOpen); |
| 361 return environment.lookup(local); | 426 return environment.lookup(local); |
| 362 } | 427 } |
| 363 | 428 |
| 364 /// Create a get access of the static [element]. | 429 /// Create a get access of the static [element]. |
| 365 ir.Primitive buildStaticGet(Element element, Selector selector) { | 430 ir.Primitive buildStaticGet(Element element, Selector selector) { |
| 366 assert(isOpen); | 431 assert(isOpen); |
| 367 assert(selector.isGetter); | 432 assert(selector.isGetter); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 /// Create a static invocation of [element] with arguments structure defined | 505 /// Create a static invocation of [element] with arguments structure defined |
| 441 /// by [selector] and argument values defined by [arguments]. | 506 /// by [selector] and argument values defined by [arguments]. |
| 442 ir.Primitive buildStaticInvocation(Element element, | 507 ir.Primitive buildStaticInvocation(Element element, |
| 443 Selector selector, | 508 Selector selector, |
| 444 List<ir.Definition> arguments) { | 509 List<ir.Definition> arguments) { |
| 445 return continueWithExpression( | 510 return continueWithExpression( |
| 446 (k) => new ir.InvokeStatic(element, selector, k, arguments)); | 511 (k) => new ir.InvokeStatic(element, selector, k, arguments)); |
| 447 } | 512 } |
| 448 | 513 |
| 449 /// Creates an if-then-else statement with the provided [condition] where the | 514 /// Creates an if-then-else statement with the provided [condition] where the |
| 450 /// then and else branches are created throught the [buildThenPart] and | 515 /// then and else branches are created through the [buildThenPart] and |
| 451 /// [buildElsePart] functions, respectively. | 516 /// [buildElsePart] functions, respectively. |
| 452 /// | 517 /// |
| 453 /// An if-then statement is created if [buildElsePart] is a no-op. | 518 /// An if-then statement is created if [buildElsePart] is a no-op. |
| 519 // TODO(johnniwinther): Unify implementation with [buildConditional] and |
| 520 // [_buildLogicalOperator]. |
| 454 void buildIf(ir.Primitive condition, | 521 void buildIf(ir.Primitive condition, |
| 455 void buildThenPart(IrBuilder builder), | 522 void buildThenPart(IrBuilder builder), |
| 456 void buildElsePart(IrBuilder builder)) { | 523 void buildElsePart(IrBuilder builder)) { |
| 457 assert(isOpen); | 524 assert(isOpen); |
| 458 | 525 |
| 459 // The then and else parts are delimited. | 526 // The then and else parts are delimited. |
| 460 IrBuilder thenBuilder = new IrBuilder.delimited(this); | 527 IrBuilder thenBuilder = new IrBuilder.delimited(this); |
| 461 IrBuilder elseBuilder = new IrBuilder.delimited(this); | 528 IrBuilder elseBuilder = new IrBuilder.delimited(this); |
| 462 buildThenPart(thenBuilder); | 529 buildThenPart(thenBuilder); |
| 463 buildElsePart(elseBuilder); | 530 buildElsePart(elseBuilder); |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 774 index = 0; | 841 index = 0; |
| 775 for (int i = 0; i < environment.length; ++i) { | 842 for (int i = 0; i < environment.length; ++i) { |
| 776 if (common[i] == null) { | 843 if (common[i] == null) { |
| 777 environment.index2value[i] = parameters[index++]; | 844 environment.index2value[i] = parameters[index++]; |
| 778 } | 845 } |
| 779 } | 846 } |
| 780 | 847 |
| 781 return join; | 848 return join; |
| 782 } | 849 } |
| 783 } | 850 } |
| OLD | NEW |