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

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: Created 5 years, 10 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 // Code for continuations with exactly one use is inlined at the use site.
karlklose 2015/02/16 10:15:48 Use '///'.
61 // This is not safe if the code is moved inside the scope of an exception
62 // handler (i.e., into a try block). We keep a stack of singly-referenced
63 // continuations that are in scope without crossing a binding for a handler.
64 List<cps_ir.Continuation> safeForHandlers = <cps_ir.Continuation>[];
65
60 ExecutableElement currentElement; 66 ExecutableElement currentElement;
61 cps_ir.Continuation returnContinuation; 67 cps_ir.Continuation returnContinuation;
62 68
63 Builder parent; 69 Builder parent;
64 70
65 Builder(this.internalError, [this.parent]); 71 Builder(this.internalError, [this.parent]);
66 72
67 Builder createInnerBuilder() { 73 Builder createInnerBuilder() {
68 return new Builder(internalError, this); 74 return new Builder(internalError, this);
69 } 75 }
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
363 return new Assign(variable, definition, visit(node.body)); 369 return new Assign(variable, definition, visit(node.body));
364 } 370 }
365 } 371 }
366 372
367 Statement visitRunnableBody(cps_ir.RunnableBody node) { 373 Statement visitRunnableBody(cps_ir.RunnableBody node) {
368 return visit(node.body); 374 return visit(node.body);
369 } 375 }
370 376
371 Statement visitLetCont(cps_ir.LetCont node) { 377 Statement visitLetCont(cps_ir.LetCont node) {
372 // Introduce labels for continuations that need them. 378 // Introduce labels for continuations that need them.
379 int safeForHandlersLengthOnEntry = safeForHandlers.length;
373 for (cps_ir.Continuation continuation in node.continuations) { 380 for (cps_ir.Continuation continuation in node.continuations) {
374 if (continuation.hasMultipleUses) { 381 if (continuation.hasMultipleUses) {
375 labels[continuation] = new Label(); 382 labels[continuation] = new Label();
383 } else {
384 safeForHandlers.add(continuation);
376 } 385 }
377 } 386 }
378 Statement body = visit(node.body); 387 Statement body = visit(node.body);
388 safeForHandlers.length = safeForHandlersLengthOnEntry;
379 // Continuations are bound at the same level, but they have to be 389 // Continuations are bound at the same level, but they have to be
380 // translated as if nested. This is because the body can invoke any 390 // translated as if nested. This is because the body can invoke any
381 // of them from anywhere, so it must be nested inside all of them. 391 // of them from anywhere, so it must be nested inside all of them.
382 // 392 //
383 // The continuation bodies are not always translated directly here because 393 // The continuation bodies are not always translated directly here because
384 // they may have been already translated: 394 // they may have been already translated:
385 // * For singly-used continuations, the continuation's body is 395 // * For singly-used continuations, the continuation's body is
386 // translated at the site of the continuation invocation. 396 // translated at the site of the continuation invocation.
387 // * For recursive continuations, there is a single non-recursive 397 // * For recursive continuations, there is a single non-recursive
388 // invocation. The continuation's body is translated at the site 398 // invocation. The continuation's body is translated at the site
389 // of the non-recursive continuation invocation. 399 // of the non-recursive continuation invocation.
390 // See visitInvokeContinuation for the implementation. 400 // See visitInvokeContinuation for the implementation.
391 Statement current = body; 401 Statement current = body;
392 for (cps_ir.Continuation continuation in node.continuations.reversed) { 402 for (cps_ir.Continuation continuation in node.continuations.reversed) {
393 Label label = labels[continuation]; 403 Label label = labels[continuation];
394 if (label != null && !continuation.isRecursive) { 404 if (label != null && !continuation.isRecursive) {
395 current = 405 current =
396 new LabeledStatement(label, current, visit(continuation.body)); 406 new LabeledStatement(label, current, visit(continuation.body));
397 } 407 }
398 } 408 }
399 return current; 409 return current;
400 } 410 }
401 411
412 Statement visitLetHandler(cps_ir.LetHandler node) {
413 List<cps_ir.Continuation> saved = safeForHandlers;
414 safeForHandlers = <cps_ir.Continuation>[];
415 Statement tryBody = visit(node.body);
416 safeForHandlers = saved;
417 List<Variable> catchParameters =
418 node.handler.parameters.map(getVariable).toList();
419 Statement catchBody = visit(node.handler.body);
420 return new TryStatement(tryBody, catchParameters, catchBody);
421 }
422
402 Statement visitInvokeStatic(cps_ir.InvokeStatic node) { 423 Statement visitInvokeStatic(cps_ir.InvokeStatic node) {
403 // Calls are translated to direct style. 424 // Calls are translated to direct style.
404 List<Expression> arguments = translateArguments(node.arguments); 425 List<Expression> arguments = translateArguments(node.arguments);
405 Expression invoke = new InvokeStatic(node.target, node.selector, arguments); 426 Expression invoke = new InvokeStatic(node.target, node.selector, arguments);
406 return continueWithExpression(node.continuation, invoke); 427 return continueWithExpression(node.continuation, invoke);
407 } 428 }
408 429
409 Statement visitInvokeMethod(cps_ir.InvokeMethod node) { 430 Statement visitInvokeMethod(cps_ir.InvokeMethod node) {
410 Expression invoke = new InvokeMethod(getVariableReference(node.receiver), 431 Expression invoke = new InvokeMethod(getVariableReference(node.receiver),
411 node.selector, 432 node.selector,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 // * Recursive continuations 521 // * Recursive continuations
501 // - There is a single non-recursive invocation. Translate 522 // - There is a single non-recursive invocation. Translate
502 // the continuation body inline as a labeled loop at the 523 // the continuation body inline as a labeled loop at the
503 // invocation site. 524 // invocation site.
504 // - Translate the recursive invocations to Continue. 525 // - Translate the recursive invocations to Continue.
505 if (cont.isRecursive) { 526 if (cont.isRecursive) {
506 return node.isRecursive 527 return node.isRecursive
507 ? new Continue(labels[cont]) 528 ? new Continue(labels[cont])
508 : new WhileTrue(labels[cont], visit(cont.body)); 529 : new WhileTrue(labels[cont], visit(cont.body));
509 } else { 530 } else {
510 return cont.hasExactlyOneUse 531 if (cont.hasExactlyOneUse) {
511 ? visit(cont.body) 532 if (safeForHandlers.contains(cont)) {
512 : new Break(labels[cont]); 533 return visit(cont.body);
534 }
535 labels[cont] = new Label();
asgerf 2015/02/20 10:10:08 I think you should create the Label inside visitLe
Kevin Millikin (Google) 2015/02/25 11:06:36 I agree that the whole thing is complicated. * Th
asgerf 2015/02/25 11:55:11 I guess we could also just let the statement rewri
536 }
537 return new Break(labels[cont]);
513 } 538 }
514 }); 539 });
515 } 540 }
516 } 541 }
517 542
518 Statement visitBranch(cps_ir.Branch node) { 543 Statement visitBranch(cps_ir.Branch node) {
519 Expression condition = visit(node.condition); 544 Expression condition = visit(node.condition);
520 Statement thenStatement, elseStatement; 545 Statement thenStatement, elseStatement;
521 cps_ir.Continuation cont = node.trueContinuation.definition; 546 cps_ir.Continuation cont = node.trueContinuation.definition;
522 assert(cont.parameters.isEmpty); 547 assert(cont.parameters.isEmpty);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 // visited. 612 // visited.
588 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.'); 613 internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.');
589 return null; 614 return null;
590 } 615 }
591 616
592 Expression visitIsTrue(cps_ir.IsTrue node) { 617 Expression visitIsTrue(cps_ir.IsTrue node) {
593 return getVariableReference(node.value); 618 return getVariableReference(node.value);
594 } 619 }
595 } 620 }
596 621
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698