Chromium Code Reviews| Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart |
| diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart |
| index c92471617d0b4cb2bf3e551e5baa3f1d08a71e5e..6d05eeca53c1e546dc81d84111136126abfdbfd2 100644 |
| --- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart |
| +++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart |
| @@ -1644,6 +1644,78 @@ abstract class IrBuilder { |
| environment = breakCollector.environment; |
| } |
| + void buildSimpleSwitch(JumpTarget target, |
| + ir.Primitive value, |
| + List<SwitchCaseInfo> cases, |
| + SwitchCaseInfo defaultCase, |
| + Element error, |
| + SourceInformation sourceInformation) { |
| + assert(isOpen); |
| + JumpCollector join = new ForwardJumpCollector(environment, target: target); |
| + |
| + IrBuilder casesBuilder = makeDelimitedBuilder(); |
| + casesBuilder.state.breakCollectors.add(join); |
| + for (SwitchCaseInfo caseInfo in cases) { |
|
asgerf
2015/06/19 12:47:34
Anonymize buildRight? I don't understand the name
Kevin Millikin (Google)
2015/06/19 12:59:52
Yeah, that's how I wrote it in my head, but I want
|
| + buildConditionFrom(int index) { |
| + ir.Primitive buildRight(IrBuilder builder) { |
| + ir.Primitive comparison = builder.addPrimitive( |
| + new ir.Identical(value, caseInfo.constants[index])); |
| + return (index == caseInfo.constants.length - 1) |
| + ? comparison |
| + : builder.buildLogicalOperator( |
| + comparison, buildConditionFrom(index + 1), isLazyOr: true); |
| + } |
| + return buildRight; |
| + } |
| + |
| + ir.Primitive condition = buildConditionFrom(0)(casesBuilder); |
| + IrBuilder thenBuilder = makeDelimitedBuilder(); |
| + caseInfo.buildBody(thenBuilder); |
| + if (thenBuilder.isOpen) { |
| + // It is a runtime error to reach the end of a switch case, unless |
| + // it is the last case. |
| + if (caseInfo == cases.last && defaultCase == null) { |
| + thenBuilder.jumpTo(join); |
| + } else { |
| + ir.Primitive exception = thenBuilder._buildInvokeStatic( |
| + error, |
| + new Selector.fromElement(error), |
| + <ir.Primitive>[], |
| + sourceInformation); |
| + thenBuilder.buildThrow(exception); |
| + } |
| + } |
| + |
| + ir.Continuation thenContinuation = new ir.Continuation([]); |
| + thenContinuation.body = thenBuilder._root; |
| + ir.Continuation elseContinuation = new ir.Continuation([]); |
| + casesBuilder.add( |
| + new ir.LetCont.many(<ir.Continuation>[elseContinuation, |
| + thenContinuation], |
| + new ir.Branch(new ir.IsTrue(condition), |
| + thenContinuation, |
| + elseContinuation))); |
|
asgerf
2015/06/19 12:47:34
The rule that the first continuation of LetCont be
Kevin Millikin (Google)
2015/06/19 12:59:52
There is a comment everywhere else, I'll duplicate
|
| + } |
| + |
| + if (defaultCase != null) { |
| + defaultCase.buildBody(casesBuilder); |
| + } |
| + if (casesBuilder.isOpen) casesBuilder.jumpTo(join); |
| + |
| + casesBuilder.state.breakCollectors.removeLast(); |
| + |
| + if (!join.isEmpty) { |
| + add(new ir.LetCont(join.continuation, casesBuilder._root)); |
| + environment = join.environment; |
| + } else if (casesBuilder._root != null) { |
| + add(casesBuilder._root); |
| + _current = casesBuilder._current; |
| + environment = casesBuilder.environment; |
| + } else { |
| + // The translation of the cases did not emit any code. |
| + } |
| + } |
| + |
| /// Creates a try-statement. |
| /// |
| /// [tryInfo] provides information on local variables declared and boxed |
| @@ -2531,3 +2603,12 @@ class CatchClauseInfo { |
| this.stackTraceVariable, |
| this.buildCatchBlock}); |
| } |
| + |
| +class SwitchCaseInfo { |
| + final List<ir.Primitive> constants = <ir.Primitive>[]; |
| + final SubbuildFunction buildBody; |
| + |
| + SwitchCaseInfo(this.buildBody); |
| + |
| + void addConstant(ir.Primitive constant) => constants.add(constant); |
| +} |