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

Side by Side Diff: pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart

Issue 923013002: dart2dart: Implementation of simple try/catch. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fixed break/continue, incorporated comments. Created 5 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) 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 final Map<Local, List<Variable>> local2variables = <Local, List<Variable>>{}; 50 final Map<Local, List<Variable>> local2variables = <Local, List<Variable>>{};
51 51
52 /// Like [local2variables], except for mutable variables. 52 /// Like [local2variables], except for mutable variables.
53 final Map<cps_ir.MutableVariable, Variable> local2mutable = 53 final Map<cps_ir.MutableVariable, Variable> local2mutable =
54 <cps_ir.MutableVariable, Variable>{}; 54 <cps_ir.MutableVariable, Variable>{};
55 55
56 // Continuations with more than one use are replaced with Tree labels. This 56 // Continuations with more than one use are replaced with Tree labels. This
57 // is the mapping from continuations to labels. 57 // is the mapping from continuations to labels.
58 final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{}; 58 final Map<cps_ir.Continuation, Label> labels = <cps_ir.Continuation, Label>{};
59 59
60 /// A stack of singly-used labels that can be safely inlined at their use
61 /// site.
62 ///
63 /// Code for continuations with exactly one use is inlined at the use site.
64 /// This is not safe if the code is moved inside the scope of an exception
65 /// handler (i.e., into a try block). We keep a stack of singly-referenced
66 /// continuations that are in scope without crossing a binding for a handler.
67 List<cps_ir.Continuation> safeForInlining = <cps_ir.Continuation>[];
68
60 ExecutableElement currentElement; 69 ExecutableElement currentElement;
61 cps_ir.Continuation returnContinuation; 70 cps_ir.Continuation returnContinuation;
62 71
63 Builder parent; 72 Builder parent;
64 73
65 Builder(this.internalError, [this.parent]); 74 Builder(this.internalError, [this.parent]);
66 75
67 Builder createInnerBuilder() { 76 Builder createInnerBuilder() {
68 return new Builder(internalError, this); 77 return new Builder(internalError, this);
69 } 78 }
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 return new Assign(variable, definition, visit(node.body)); 374 return new Assign(variable, definition, visit(node.body));
366 } 375 }
367 } 376 }
368 377
369 Statement visitRunnableBody(cps_ir.RunnableBody node) { 378 Statement visitRunnableBody(cps_ir.RunnableBody node) {
370 return visit(node.body); 379 return visit(node.body);
371 } 380 }
372 381
373 Statement visitLetCont(cps_ir.LetCont node) { 382 Statement visitLetCont(cps_ir.LetCont node) {
374 // Introduce labels for continuations that need them. 383 // Introduce labels for continuations that need them.
384 int safeForInliningLengthOnEntry = safeForInlining.length;
375 for (cps_ir.Continuation continuation in node.continuations) { 385 for (cps_ir.Continuation continuation in node.continuations) {
376 if (continuation.hasMultipleUses) { 386 if (continuation.hasMultipleUses) {
377 labels[continuation] = new Label(); 387 labels[continuation] = new Label();
388 } else {
389 safeForInlining.add(continuation);
378 } 390 }
379 } 391 }
380 Statement body = visit(node.body); 392 Statement body = visit(node.body);
393 safeForInlining.length = safeForInliningLengthOnEntry;
381 // Continuations are bound at the same level, but they have to be 394 // Continuations are bound at the same level, but they have to be
382 // translated as if nested. This is because the body can invoke any 395 // translated as if nested. This is because the body can invoke any
383 // of them from anywhere, so it must be nested inside all of them. 396 // of them from anywhere, so it must be nested inside all of them.
384 // 397 //
385 // The continuation bodies are not always translated directly here because 398 // The continuation bodies are not always translated directly here because
386 // they may have been already translated: 399 // they may have been already translated:
387 // * For singly-used continuations, the continuation's body is 400 // * For singly-used continuations, the continuation's body is
388 // translated at the site of the continuation invocation. 401 // translated at the site of the continuation invocation.
389 // * For recursive continuations, there is a single non-recursive 402 // * For recursive continuations, there is a single non-recursive
390 // invocation. The continuation's body is translated at the site 403 // invocation. The continuation's body is translated at the site
391 // of the non-recursive continuation invocation. 404 // of the non-recursive continuation invocation.
392 // See visitInvokeContinuation for the implementation. 405 // See visitInvokeContinuation for the implementation.
393 Statement current = body; 406 Statement current = body;
394 for (cps_ir.Continuation continuation in node.continuations.reversed) { 407 for (cps_ir.Continuation continuation in node.continuations.reversed) {
395 Label label = labels[continuation]; 408 Label label = labels[continuation];
396 if (label != null && !continuation.isRecursive) { 409 if (label != null && !continuation.isRecursive) {
397 current = 410 current =
398 new LabeledStatement(label, current, visit(continuation.body)); 411 new LabeledStatement(label, current, visit(continuation.body));
399 } 412 }
400 } 413 }
401 return current; 414 return current;
402 } 415 }
403 416
417 Statement visitLetHandler(cps_ir.LetHandler node) {
418 List<cps_ir.Continuation> saved = safeForInlining;
419 safeForInlining = <cps_ir.Continuation>[];
420 Statement tryBody = visit(node.body);
421 safeForInlining = saved;
422 List<Variable> catchParameters =
423 node.handler.parameters.map(getVariable).toList();
424 Statement catchBody = visit(node.handler.body);
425 return new Try(tryBody, catchParameters, catchBody);
426 }
427
404 Statement visitInvokeStatic(cps_ir.InvokeStatic node) { 428 Statement visitInvokeStatic(cps_ir.InvokeStatic node) {
405 // Calls are translated to direct style. 429 // Calls are translated to direct style.
406 List<Expression> arguments = translateArguments(node.arguments); 430 List<Expression> arguments = translateArguments(node.arguments);
407 Expression invoke = new InvokeStatic(node.target, node.selector, arguments); 431 Expression invoke = new InvokeStatic(node.target, node.selector, arguments);
408 return continueWithExpression(node.continuation, invoke); 432 return continueWithExpression(node.continuation, invoke);
409 } 433 }
410 434
411 Statement visitInvokeMethod(cps_ir.InvokeMethod node) { 435 Statement visitInvokeMethod(cps_ir.InvokeMethod node) {
412 Expression invoke = new InvokeMethod(getVariableReference(node.receiver), 436 Expression invoke = new InvokeMethod(getVariableReference(node.receiver),
413 node.selector, 437 node.selector,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 // * Recursive continuations 526 // * Recursive continuations
503 // - There is a single non-recursive invocation. Translate 527 // - There is a single non-recursive invocation. Translate
504 // the continuation body inline as a labeled loop at the 528 // the continuation body inline as a labeled loop at the
505 // invocation site. 529 // invocation site.
506 // - Translate the recursive invocations to Continue. 530 // - Translate the recursive invocations to Continue.
507 if (cont.isRecursive) { 531 if (cont.isRecursive) {
508 return node.isRecursive 532 return node.isRecursive
509 ? new Continue(labels[cont]) 533 ? new Continue(labels[cont])
510 : new WhileTrue(labels[cont], visit(cont.body)); 534 : new WhileTrue(labels[cont], visit(cont.body));
511 } else { 535 } else {
512 return cont.hasExactlyOneUse 536 if (cont.hasExactlyOneUse) {
513 ? visit(cont.body) 537 if (safeForInlining.contains(cont)) {
514 : new Break(labels[cont]); 538 return visit(cont.body);
539 }
540 labels[cont] = new Label();
541 }
542 return new Break(labels[cont]);
515 } 543 }
516 }); 544 });
517 } 545 }
518 } 546 }
519 547
520 Statement visitBranch(cps_ir.Branch node) { 548 Statement visitBranch(cps_ir.Branch node) {
521 Expression condition = visit(node.condition); 549 Expression condition = visit(node.condition);
522 Statement thenStatement, elseStatement; 550 Statement thenStatement, elseStatement;
523 cps_ir.Continuation cont = node.trueContinuation.definition; 551 cps_ir.Continuation cont = node.trueContinuation.definition;
524 assert(cont.parameters.isEmpty); 552 assert(cont.parameters.isEmpty);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 // visited. 617 // visited.
590 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.'); 618 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.');
591 return null; 619 return null;
592 } 620 }
593 621
594 Expression visitIsTrue(cps_ir.IsTrue node) { 622 Expression visitIsTrue(cps_ir.IsTrue node) {
595 return getVariableReference(node.value); 623 return getVariableReference(node.value);
596 } 624 }
597 } 625 }
598 626
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698