Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: frog/leg/ssa/builder.dart

Issue 9632018: Switch-implementation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Finished implementation Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
613 final HBreak breakInstruction; 613 final HBreak breakInstruction;
614 final LocalsHandler locals; 614 final LocalsHandler locals;
615 BreakHandlerEntry(this.breakInstruction, this.locals); 615 BreakHandlerEntry(this.breakInstruction, this.locals);
616 } 616 }
617 617
618 interface BreakHandler default BreakHandlerImpl { 618 interface BreakHandler default BreakHandlerImpl {
619 BreakHandler(SsaBuilder builder, StatementElement target); 619 BreakHandler(SsaBuilder builder, StatementElement target);
620 void addBreak(HBreak breakInstruction, LocalsHandler locals); 620 void addBreak(HBreak breakInstruction, LocalsHandler locals);
621 void forEachBreak(Function action); 621 void forEachBreak(Function action);
622 void close(); 622 void close();
623 List<SourceString> labels(); 623 List<LabelElement> labels();
624 } 624 }
625 625
626 // Inert break handler used to avoid null checks when a loop isn't 626 // Inert break handler used to avoid null checks when a loop isn't
627 // used as the target of a break, and therefore doesn't need a break 627 // used as the target of a break, and therefore doesn't need a break
628 // handler associated with it. 628 // handler associated with it.
629 class NullBreakHandler implements BreakHandler { 629 class NullBreakHandler implements BreakHandler {
630 const NullBreakHandler(); 630 const NullBreakHandler();
631 void addBreak(HBreak breakInstruction, LocalsHandler locals) { 631 void addBreak(HBreak breakInstruction, LocalsHandler locals) {
632 unreachable(); 632 unreachable();
633 } 633 }
634 void forEachBreak(Function ignored) { } 634 void forEachBreak(Function ignored) { }
635 void close() { } 635 void close() { }
636 List<SourceString> labels() => const <SourceString>[]; 636 List<LabelElement> labels() => const <LabelElement>[];
637 } 637 }
638 638
639 // Records breaks until a target block is available. 639 // Records breaks until a target block is available.
640 // Breaks are always forward jumps. 640 // Breaks are always forward jumps.
641 class BreakHandlerImpl implements BreakHandler { 641 class BreakHandlerImpl implements BreakHandler {
642 final BreakHandler previous; 642 final BreakHandler previous;
643 final SsaBuilder builder; 643 final SsaBuilder builder;
644 final StatementElement target; 644 final StatementElement target;
645 final List<BreakHandlerEntry> breaks; 645 final List<BreakHandlerEntry> breaks;
646 BreakHandlerImpl(SsaBuilder builder, this.target) 646 BreakHandlerImpl(SsaBuilder builder, this.target)
(...skipping 15 matching lines...) Expand all
662 } 662 }
663 } 663 }
664 664
665 void close() { 665 void close() {
666 assert(builder.currentBreakHandler === this); 666 assert(builder.currentBreakHandler === this);
667 // The mapping from StatementElement to BreakHandler is no longer needed. 667 // The mapping from StatementElement to BreakHandler is no longer needed.
668 builder.breakTargets.remove(target); 668 builder.breakTargets.remove(target);
669 builder.currentBreakHandler = previous; 669 builder.currentBreakHandler = previous;
670 } 670 }
671 671
672 List<SourceString> labels() { 672 List<LabelElement> labels() {
673 List<SourceString> result = null; 673 List<LabelElement> result = null;
674 for (LabelElement element in target.labels) { 674 for (LabelElement element in target.labels) {
675 if (element.isBreakTarget) { 675 if (element.isBreakTarget) {
676 if (result === null) result = <SourceString>[]; 676 if (result === null) result = <LabelElement>[];
677 result.add(element.label.source); 677 result.add(element);
678 } 678 }
679 } 679 }
680 return (result === null) ? const <SourceString>[] : result; 680 return (result === null) ? const <LabelElement>[] : result;
681 } 681 }
682 } 682 }
683 683
684 class SsaBuilder implements Visitor { 684 class SsaBuilder implements Visitor {
685 final Compiler compiler; 685 final Compiler compiler;
686 TreeElements elements; 686 TreeElements elements;
687 final Interceptors interceptors; 687 final Interceptors interceptors;
688 final WorkItem work; 688 final WorkItem work;
689 bool methodInterceptionEnabled; 689 bool methodInterceptionEnabled;
690 HGraph graph; 690 HGraph graph;
691 LocalsHandler localsHandler; 691 LocalsHandler localsHandler;
692 HInstruction rethrowableException; 692 HInstruction rethrowableException;
693 693
694 Map<StatementElement, BreakHandler> breakTargets; 694 Map<StatementElement, BreakHandler> breakTargets;
695 695
696 // We build the Ssa graph by simulating a stack machine. 696 // We build the Ssa graph by simulating a stack machine.
697 List<HInstruction> stack; 697 List<HInstruction> stack;
698 698
699 // The current block to add instructions to. Might be null, if we are 699 // The current block to add instructions to. Might be null, if we are
700 // visiting dead code. 700 // visiting dead code.
701 HBasicBlock current; 701 HBasicBlock current;
702 // The most recently opened block. Has the same value as [current] while 702 // The most recently opened block. Has the same value as [current] while
703 // the block is open, but unlike [current], it isn't cleared when the current 703 // the block is open, but unlike [current], it isn't cleared when the current
704 // block is closed. 704 // block is closed.
705 HBasicBlock lastOpenedBlock; 705 HBasicBlock lastOpenedBlock;
706 706
707 // Linked list of active break-handlers. Will be removed in the order 707 // Linked list of active break-handlers. Will be removed in the order
708 // they are added. 708 // they are added.
709 BreakHandler currentBreakHandler = const NullBreakHandler(); 709 BreakHandler currentBreakHandler = const NullBreakHandler();
710 // The break handler to use for an upcoming loop statement (temporarily set
711 // if a labeled statement is labeling a loop).
712 BreakHandler loopBreakHandler = null;
713 710
714 SsaBuilder(Compiler compiler, WorkItem work) 711 SsaBuilder(Compiler compiler, WorkItem work)
715 : this.compiler = compiler, 712 : this.compiler = compiler,
716 this.work = work, 713 this.work = work,
717 interceptors = compiler.builder.interceptors, 714 interceptors = compiler.builder.interceptors,
718 methodInterceptionEnabled = true, 715 methodInterceptionEnabled = true,
719 elements = work.resolutionTree, 716 elements = work.resolutionTree,
720 graph = new HGraph(), 717 graph = new HGraph(),
721 stack = new List<HInstruction>(), 718 stack = new List<HInstruction>(),
722 breakTargets = new Map<StatementElement, BreakHandler>() { 719 breakTargets = new Map<StatementElement, BreakHandler>() {
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 } 998 }
1002 999
1003 /** 1000 /**
1004 * Creates a new loop-header block. The previous [current] block 1001 * Creates a new loop-header block. The previous [current] block
1005 * is closed with an [HGoto] and replaced by the newly created block. 1002 * is closed with an [HGoto] and replaced by the newly created block.
1006 * Also notifies the locals handler that we're entering a loop. 1003 * Also notifies the locals handler that we're entering a loop.
1007 */ 1004 */
1008 BreakHandler beginLoopHeader(Node node) { 1005 BreakHandler beginLoopHeader(Node node) {
1009 assert(!isAborted()); 1006 assert(!isAborted());
1010 HBasicBlock previousBlock = close(new HGoto()); 1007 HBasicBlock previousBlock = close(new HGoto());
1011 BreakHandler breakHandler = getLoopBreakHandler(node); 1008 BreakHandler breakHandler = getBreakHandler(node);
1012 HBasicBlock loopEntry = graph.addNewLoopHeaderBlock(breakHandler.labels()); 1009 HBasicBlock loopEntry = graph.addNewLoopHeaderBlock(breakHandler.labels());
1013 previousBlock.addSuccessor(loopEntry); 1010 previousBlock.addSuccessor(loopEntry);
1014 open(loopEntry); 1011 open(loopEntry);
1015 1012
1016 localsHandler.beginLoopHeader(node, loopEntry); 1013 localsHandler.beginLoopHeader(node, loopEntry);
1017 return breakHandler; 1014 return breakHandler;
1018 } 1015 }
1019 1016
1020 /** 1017 /**
1021 * Ends the loop: 1018 * Ends the loop:
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
1644 SourceString name = selector.namedArguments[i]; 1641 SourceString name = selector.namedArguments[i];
1645 if (name == parameter.name) { 1642 if (name == parameter.name) {
1646 foundIndex = i; 1643 foundIndex = i;
1647 break; 1644 break;
1648 } 1645 }
1649 } 1646 }
1650 if (foundIndex != -1) { 1647 if (foundIndex != -1) {
1651 list.add(namedArguments[foundIndex]); 1648 list.add(namedArguments[foundIndex]);
1652 } else { 1649 } else {
1653 Constant constant = compiler.compileVariable(parameter); 1650 Constant constant = compiler.compileVariable(parameter);
1654 list.add(graph.addConstant(constant)); 1651 list.add(graph.addConstant(constant));
1655 } 1652 }
1656 } 1653 }
1657 } 1654 }
1658 } 1655 }
1659 1656
1660 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) { 1657 void addGenericSendArgumentsToList(Link<Node> link, List<HInstruction> list) {
1661 for (; !link.isEmpty(); link = link.tail) { 1658 for (; !link.isEmpty(); link = link.tail) {
1662 visit(link.head); 1659 visit(link.head);
1663 list.add(pop()); 1660 list.add(pop());
1664 } 1661 }
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
2116 visitBreakStatement(BreakStatement node) { 2113 visitBreakStatement(BreakStatement node) {
2117 work.allowSpeculativeOptimization = false; 2114 work.allowSpeculativeOptimization = false;
2118 assert(!isAborted()); 2115 assert(!isAborted());
2119 StatementElement target = elements[node]; 2116 StatementElement target = elements[node];
2120 assert(target !== null); 2117 assert(target !== null);
2121 BreakHandler handler = breakTargets[target]; 2118 BreakHandler handler = breakTargets[target];
2122 assert(handler !== null); 2119 assert(handler !== null);
2123 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler); 2120 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
2124 HBreak breakInstruction; 2121 HBreak breakInstruction;
2125 if (node.target === null) { 2122 if (node.target === null) {
2126 breakInstruction = new HBreak(); 2123 breakInstruction = new HBreak(target);
2127 } else { 2124 } else {
2128 breakInstruction = new HBreak(node.target.source); 2125 LabelElement label = elements[node.target];
2126 breakInstruction = new HBreak(label);
2129 } 2127 }
2130 close(breakInstruction); 2128 close(breakInstruction);
2131 handler.addBreak(breakInstruction, savedLocals); 2129 handler.addBreak(breakInstruction, savedLocals);
2132 } 2130 }
2133 2131
2134 visitContinueStatement(ContinueStatement node) { 2132 visitContinueStatement(ContinueStatement node) {
2135 // TODO(lrn): Replace this with a real implementation of continue. 2133 // TODO(lrn): Replace this with a real implementation of continue.
2136 compiler.reportWarning(node, 'continue not implemented'); 2134 compiler.reportWarning(node, 'continue not implemented');
2137 generateUnimplemented('continue not implemented'); 2135 generateUnimplemented('continue not implemented');
2138 } 2136 }
2139 2137
2140 BreakHandler getLoopBreakHandler(Node node) { 2138 BreakHandler getBreakHandler(Node node) {
2141 StatementElement element = elements[node]; 2139 StatementElement element = elements[node];
2142 BreakHandler handler; 2140 if (element === null) return const NullBreakHandler();
2143 if (loopBreakHandler === null) { 2141 return new BreakHandler(this, element);
2144 if (element === null) return const NullBreakHandler();
2145 handler = new BreakHandler(this, element);
2146 } else {
2147 handler = loopBreakHandler;
2148 loopBreakHandler = null;
2149 if (element === null) return handler;
2150 }
2151 return handler;
2152 } 2142 }
2153 2143
2154 visitForInStatement(ForInStatement node) { 2144 visitForInStatement(ForInStatement node) {
2155 // Generate a structure equivalent to: 2145 // Generate a structure equivalent to:
2156 // Iterator<E> $iter = <iterable>.iterator() 2146 // Iterator<E> $iter = <iterable>.iterator()
2157 // while ($iter.hasNext()) { 2147 // while ($iter.hasNext()) {
2158 // E <declaredIdentifier> = $iter.next(); 2148 // E <declaredIdentifier> = $iter.next();
2159 // <body> 2149 // <body>
2160 // } 2150 // }
2161 localsHandler.startLoop(node); 2151 localsHandler.startLoop(node);
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2269 if (!isAborted()) { 2259 if (!isAborted()) {
2270 goto(current, joinBlock); 2260 goto(current, joinBlock);
2271 breakLocals.add(localsHandler); 2261 breakLocals.add(localsHandler);
2272 } 2262 }
2273 open(joinBlock); 2263 open(joinBlock);
2274 localsHandler = beforeLocals.mergeMultiple(breakLocals, joinBlock); 2264 localsHandler = beforeLocals.mergeMultiple(breakLocals, joinBlock);
2275 2265
2276 if (hasBreak) { 2266 if (hasBreak) {
2277 // There was at least one reachable break, so the label is needed. 2267 // There was at least one reachable break, so the label is needed.
2278 HLabeledBlockInformation blockInfo = 2268 HLabeledBlockInformation blockInfo =
2279 new HLabeledBlockInformation(bodyGraph, joinBlock, handler.labels()); 2269 new HLabeledBlockInformation(
floitsch 2012/03/09 16:52:15 keep on one line.
2270 bodyGraph, joinBlock, handler.labels());
2280 entryBlock.labeledBlockInformation = blockInfo; 2271 entryBlock.labeledBlockInformation = blockInfo;
2281 } 2272 }
2282 handler.close(); 2273 handler.close();
2283 } 2274 }
2284 2275
2285 visitLiteralMap(LiteralMap node) { 2276 visitLiteralMap(LiteralMap node) {
2286 List<HInstruction> inputs = <HInstruction>[]; 2277 List<HInstruction> inputs = <HInstruction>[];
2287 for (Link<Node> link = node.entries.nodes; 2278 for (Link<Node> link = node.entries.nodes;
2288 !link.isEmpty(); 2279 !link.isEmpty();
2289 link = link.tail) { 2280 link = link.tail) {
(...skipping 13 matching lines...) Expand all
2303 visit(node.value); 2294 visit(node.value);
2304 visit(node.key); 2295 visit(node.key);
2305 } 2296 }
2306 2297
2307 visitNamedArgument(NamedArgument node) { 2298 visitNamedArgument(NamedArgument node) {
2308 visit(node.expression); 2299 visit(node.expression);
2309 } 2300 }
2310 2301
2311 visitSwitchStatement(SwitchStatement node) { 2302 visitSwitchStatement(SwitchStatement node) {
2312 work.allowSpeculativeOptimization = false; 2303 work.allowSpeculativeOptimization = false;
2304 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
2305 HBasicBlock startBlock = graph.addNewBlock();
2306 goto(current, startBlock);
2307 open(startBlock);
2313 visit(node.expression); 2308 visit(node.expression);
2314 HInstruction expression = pop(); 2309 HInstruction expression = pop();
2310 if (node.cases.isEmpty()) {
2311 return;
2312 }
2315 Link<Node> cases = node.cases.nodes; 2313 Link<Node> cases = node.cases.nodes;
2316 int count = 0; 2314 Element equalsHelper = interceptors.getEqualsInterceptor();
2317 handleThen() { 2315 HInstruction target = new HStatic(equalsHelper);
2318 if (cases.head.statements.nodes.isEmpty()) { 2316 add(target);
2319 compiler.unimplemented('fall-through', node: cases.head); 2317
2318 BreakHandler breakHandler = getBreakHandler(node);
2319
2320 void buildCompare(Expression caseExpression) {
floitsch 2012/03/09 16:52:15 Can't you move buildCompare and buildThrow into bu
Lasse Reichstein Nielsen 2012/03/12 13:05:23 I'll inline them.
2321 visit(caseExpression);
2322 push(new HEquals(target, pop(), expression));
2323 }
floitsch 2012/03/09 16:52:15 please add a newline after function declarations.
Lasse Reichstein Nielsen 2012/03/12 13:05:23 Done.
2324 void buildThrow() {
2325 Element element =
2326 compiler.findHelper(const SourceString("getFallThroughError"));
2327 push(new HStatic(element));
2328 HInstruction error = new HInvokeStatic(
2329 Selector.INVOCATION_0, <HInstruction>[pop()]);
2330 add(error);
2331 close(new HThrow(error));
2332 }
2333 buildSwitchCases(cases, buildCompare, buildThrow);
2334
2335 HBasicBlock lastBlock = lastOpenedBlock;
2336
2337 // Create merge block for break targets.
2338 HBasicBlock joinBlock = new HBasicBlock();
2339 List<LocalsHandler> caseLocals = <LocalsHandler>[];
2340 breakHandler.forEachBreak((HBreak instruction, LocalsHandler locals) {
2341 instruction.block.addSuccessor(joinBlock);
2342 caseLocals.add(locals);
2343 });
2344 if (!isAborted()) {
2345 caseLocals.add(localsHandler);
2346 }
2347 if (caseLocals.length != 0) {
2348 graph.addBlock(joinBlock);
2349 if (!isAborted()) {
2350 goto(current, joinBlock);
2320 } 2351 }
2321 visit(cases.head.statements); 2352 open(joinBlock);
2322 cases = cases.tail; 2353 if (caseLocals.length == 1) {
2354 localsHandler = caseLocals[0];
2355 } else {
2356 localsHandler = savedLocals.mergeMultiple(caseLocals, joinBlock);
2357 }
2358 } else {
2359 // The joinblock is not used.
2360 joinBlock = null;
2323 } 2361 }
2324 handleElse() { 2362 startBlock.labeledBlockInformation = new HLabeledBlockInformation.implicit(
2325 if (cases.isEmpty()) return; 2363 new SubGraph(startBlock, lastBlock),
2326 if (cases.head.asDefaultCase() !== null) { 2364 joinBlock,
2327 stack.add(graph.addConstantBool(true)); 2365 elements[node]);
2328 if (!cases.tail.isEmpty()) { 2366 }
2329 compiler.unimplemented('default case not last', node: cases.head); 2367
2330 } 2368
2331 } else { 2369 // Recursively build an if/else structure to match the cases.
2332 SwitchCase switchCase = cases.head; 2370 buildSwitchCases(Link<Node> cases,
2333 visit(switchCase.expression); 2371 Function buildCompare,
2334 HInstruction caseExpression = pop(); 2372 Function buildThrow) {
2335 Element equalsHelper = interceptors.getEqualsInterceptor(); 2373 SwitchCase node = cases.head;
2336 HInstruction target = new HStatic(equalsHelper); 2374 // TODO(lrn): Handle labels and continues.
2337 add(target); 2375
2338 push(new HEquals(target, caseExpression, expression)); 2376 // Called for the statements on all but the last case block.
2377 // Ensures that a user expecting a fallthrough gets an error.
2378 void visitStatementsAndAbort() {
2379 visit(node.statements);
2380 if (!isAborted()) {
2381 compiler.reportWarning(node, 'Missing break at end of switch case');
2382 buildThrow();
2339 } 2383 }
2340 handleIf(handleThen, handleElse);
2341 } 2384 }
2342 2385
2343 localsHandler.startLoop(node); 2386 Link<Node> expressions = node.expressions.nodes;
2344 BreakHandler breakHandler = beginLoopHeader(node); 2387 if (expressions.isEmpty()) {
2345 HBasicBlock loopEntryBlock = current; 2388 // Default case with no expressions.
2346 localsHandler.enterLoopBody(node); 2389 if (!node.isDefaultCase) {
2347 2390 compiler.internalError("Case with no expression and not default");
2348 handleElse(); 2391 }
2349 2392 visit(node.statements);
2350 if (isAborted()) { 2393 return;
2351 compiler.unimplemented("SsaBuilder for loop with aborting body",
2352 node: node);
2353 } 2394 }
2354 2395
2355 HBasicBlock bodyExitBlock = close(new HGoto()); 2396 // Recursively build the test conditions.
2356 HBasicBlock conditionBlock = addNewBlock(); 2397 HInstruction buildTests(Link<Node> expressions, HInstruction left) {
floitsch 2012/03/09 16:52:15 This looks a lot like the visitLogicalAndOr. I vot
Lasse Reichstein Nielsen 2012/03/12 13:05:23 Good idea.
2357 bodyExitBlock.addSuccessor(conditionBlock); 2398 // previous is a boolean instruction.
floitsch 2012/03/09 16:52:15 'previous' is still here.
Lasse Reichstein Nielsen 2012/03/12 13:05:23 Not any more. And good riddance.
2358 open(conditionBlock); 2399 if (expressions.isEmpty()) return left;
2359 stack.add(graph.addConstantBool(false)); 2400 push(new HNot(left));
2360 2401
2361 conditionBlock = close(new HLoopBranch(popBoolified(), 2402 HIf branch = new HIf(pop(), false);
2362 HLoopBranch.DO_WHILE_LOOP)); 2403 HBasicBlock leftBlock = close(branch);
2404 LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
2363 2405
2364 conditionBlock.addSuccessor(loopEntryBlock); // The back-edge. 2406 HBasicBlock rightBlock = addNewBlock();
2365 loopEntryBlock.postProcessLoopHeader(); 2407 leftBlock.addSuccessor(rightBlock);
2408 open(rightBlock);
2366 2409
2367 endLoop(loopEntryBlock, conditionBlock, breakHandler); 2410 buildCompare(expressions.head);
2411 HInstruction right = buildTests(expressions.tail, popBoolified());
2412
2413 SubGraph rightGraph = new SubGraph(rightBlock, current);
2414
2415 rightBlock = close(new HGoto());
2416 HBasicBlock joinBlock = addNewBlock();
2417 leftBlock.addSuccessor(joinBlock);
2418 rightBlock.addSuccessor(joinBlock);
2419 open(joinBlock);
2420
2421 branch.blockInformation =
2422 new HIfBlockInformation(branch, rightGraph, null, joinBlock);
2423
2424 localsHandler.mergeWith(savedLocals, joinBlock);
2425 HPhi result = new HPhi.manyInputs(null, [left, right]);
2426 joinBlock.addPhi(result);
2427 return result;
2428 }
2429
2430 buildCompare(expressions.head);
2431 HInstruction result = buildTests(expressions.tail, popBoolified());
2432
2433 if (node.isDefaultCase) {
2434 // Don't actually use the condition result.
2435 visitStatementsAndAbort();
2436 } else {
2437 stack.add(result);
2438 if (cases.tail.isEmpty()) {
2439 handleIf(() { visit(node.statements); }, null);
2440 } else {
2441 handleIf(() { visitStatementsAndAbort(); },
2442 () { buildSwitchCases(cases.tail,
2443 buildCompare, buildThrow); });
2444 }
2445 }
2446 }
2447
2448 visitSwitchCase(SwitchCase node) {
2449 unreachable();
2368 } 2450 }
2369 2451
2370 visitTryStatement(TryStatement node) { 2452 visitTryStatement(TryStatement node) {
2371 work.allowSpeculativeOptimization = false; 2453 work.allowSpeculativeOptimization = false;
2372 assert(!work.isBailoutVersion()); 2454 assert(!work.isBailoutVersion());
2373 HBasicBlock enterBlock = graph.addNewBlock(); 2455 HBasicBlock enterBlock = graph.addNewBlock();
2374 close(new HGoto()).addSuccessor(enterBlock); 2456 close(new HGoto()).addSuccessor(enterBlock);
2375 open(enterBlock); 2457 open(enterBlock);
2376 HTry tryInstruction = new HTry(); 2458 HTry tryInstruction = new HTry();
2377 List<HBasicBlock> blocks = <HBasicBlock>[]; 2459 List<HBasicBlock> blocks = <HBasicBlock>[];
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
2489 // Normally, we would call [close] here. However, then we hit 2571 // Normally, we would call [close] here. However, then we hit
2490 // another unimplemented feature: aborting loop body. Simply 2572 // another unimplemented feature: aborting loop body. Simply
2491 // calling [add] does not work as it asserts that the instruction 2573 // calling [add] does not work as it asserts that the instruction
2492 // isn't a control flow instruction. So we inline parts of [add]. 2574 // isn't a control flow instruction. So we inline parts of [add].
2493 current.addAfter(current.last, new HThrow(message)); 2575 current.addAfter(current.last, new HThrow(message));
2494 if (isExpression) { 2576 if (isExpression) {
2495 stack.add(graph.addConstantNull()); 2577 stack.add(graph.addConstantNull());
2496 } 2578 }
2497 } 2579 }
2498 } 2580 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698