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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart

Issue 979813002: Support simple try in analyzer2dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. 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
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 part of dart2js.ir_builder; 5 part of dart2js.ir_builder;
6 6
7 /** 7 /**
8 * This task iterates through all resolved elements and builds [ir.Node]s. The 8 * This task iterates through all resolved elements and builds [ir.Node]s. The
9 * nodes are stored in the [nodes] map and accessible through [hasIr] and 9 * nodes are stored in the [nodes] map and accessible through [hasIr] and
10 * [getIr]. 10 * [getIr].
(...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 // where (C', x) = Build(e, C) 446 // where (C', x) = Build(e, C)
447 // 447 //
448 // Return without a subexpression is translated as if it were return null. 448 // Return without a subexpression is translated as if it were return null.
449 ir.Primitive visitReturn(ast.Return node) { 449 ir.Primitive visitReturn(ast.Return node) {
450 assert(irBuilder.isOpen); 450 assert(irBuilder.isOpen);
451 assert(invariant(node, node.beginToken.value != 'native')); 451 assert(invariant(node, node.beginToken.value != 'native'));
452 irBuilder.buildReturn(build(node.expression)); 452 irBuilder.buildReturn(build(node.expression));
453 return null; 453 return null;
454 } 454 }
455 455
456 ir.Primitive visitTryStatement(ast.TryStatement node) { 456 visitTryStatement(ast.TryStatement node) {
457 assert(this.irBuilder.isOpen);
458 // Try/catch is not yet implemented in the JS backend. 457 // Try/catch is not yet implemented in the JS backend.
459 if (this.irBuilder.tryStatements == null) { 458 if (this.irBuilder.tryStatements == null) {
460 return giveup(node, 'try/catch in the JS backend'); 459 return giveup(node, 'try/catch in the JS backend');
461 } 460 }
462 // Multiple catch blocks are not yet implemented. 461 // Multiple catch blocks are not yet implemented.
463 if (node.catchBlocks.isEmpty || 462 if (node.catchBlocks.isEmpty ||
464 node.catchBlocks.nodes.tail == null) { 463 node.catchBlocks.nodes.tail == null) {
465 return giveup(node, 'not exactly one catch block'); 464 return giveup(node, 'not exactly one catch block');
466 } 465 }
467 // 'on T' catch blocks are not yet implemented. 466 // 'on T' catch blocks are not yet implemented.
468 if ((node.catchBlocks.nodes.head as ast.CatchBlock).onKeyword != null) { 467 if ((node.catchBlocks.nodes.head as ast.CatchBlock).onKeyword != null) {
469 return giveup(node, '"on T" catch block'); 468 return giveup(node, '"on T" catch block');
470 } 469 }
471 // Finally blocks are not yet implemented. 470 // Finally blocks are not yet implemented.
472 if (node.finallyBlock != null) { 471 if (node.finallyBlock != null) {
473 return giveup(node, 'try/finally'); 472 return giveup(node, 'try/finally');
474 } 473 }
475 474
476 // Catch handlers are in scope for their body. The CPS translation of 475 List<CatchClauseInfo> catchClauseInfos = <CatchClauseInfo>[];
477 // [[try tryBlock catch (e) catchBlock; successor]] is: 476 for (ast.CatchBlock catchClause in node.catchBlocks.nodes) {
478 // 477 assert(catchClause.exception != null);
479 // let cont join(v0, v1, ...) = [[successor]] in 478 LocalVariableElement exceptionVariable = elements[catchClause.exception];
480 // let mutable m0 = x0 in 479 LocalVariableElement stackTraceVariable;
481 // let mutable m1 = x1 in 480 if (catchClause.trace != null) {
482 // ... 481 stackTraceVariable = elements[catchClause.trace];
483 // let handler catch_(e) = 482 }
484 // let prim p0 = GetMutable(m0) in 483 catchClauseInfos.add(new CatchClauseInfo(
485 // let prim p1 = GetMutable(m1) in 484 exceptionVariable: exceptionVariable,
486 // ... 485 stackTraceVariable: stackTraceVariable,
487 // [[catchBlock]] 486 buildCatchBlock: subbuild(catchClause.block)));
488 // join(p0, p1, ...)
489 // in
490 // [[tryBlock]]
491 // let prim p0' = GetMutable(m0) in
492 // let prim p1' = GetMutable(m1) in
493 // ...
494 // join(p0', p1', ...)
495 //
496 // In other words, both the try and catch block are in the scope of the
497 // join-point continuation, and they are both in the scope of a sequence
498 // of mutable bindings for the variables assigned in the try. The join-
499 // point continuation is not in the scope of these mutable bindings.
500 // The tryBlock is in the scope of a binding for the catch handler. Each
501 // instruction (specifically, each call) in the tryBlock is in the dynamic
502 // scope of the handler. The mutable bindings are dereferenced at the end
503 // of the try block and at the beginning of the catch block, so the
504 // variables are unboxed in the catch block and at the join point.
505
506 IrBuilder tryCatchBuilder = irBuilder.makeDelimitedBuilder();
507 TryStatementInfo tryInfo = tryCatchBuilder.tryStatements[node];
508 // Variables that are boxed due to being captured in a closure are boxed
509 // for their entire lifetime, and so they do not need to be boxed on
510 // entry to any try block. We check for them here because we can not
511 // identify all of them in the same pass where we identify the variables
512 // assigned in the try (the may be captured by a closure after the try
513 // statement).
514 Iterable<LocalVariableElement> boxedOnEntry =
515 tryInfo.boxedOnEntry.where((LocalVariableElement variable) {
516 return !tryCatchBuilder.mutableCapturedVariables.contains(variable);
517 });
518 for (LocalVariableElement variable in boxedOnEntry) {
519 assert(!tryCatchBuilder.isInMutableVariable(variable));
520 ir.Primitive value = tryCatchBuilder.buildLocalGet(variable);
521 tryCatchBuilder.makeMutableVariable(variable);
522 tryCatchBuilder.declareLocalVariable(variable, initialValue: value);
523 } 487 }
524 488
525 IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder(); 489 irBuilder.buildTry(
526 IrBuilder tryBuilder = tryCatchBuilder.makeDelimitedBuilder(); 490 tryStatementInfo: irBuilder.tryStatements[node],
527 List<ir.Parameter> joinParameters = 491 buildTryBlock: subbuild(node.tryBlock),
528 new List<ir.Parameter>.generate(irBuilder.environment.length, (i) { 492 catchClauseInfos: catchClauseInfos);
529 return new ir.Parameter(irBuilder.environment.index2variable[i]);
530 });
531 ir.Continuation joinContinuation = new ir.Continuation(joinParameters);
532
533 void interceptJumps(JumpCollector collector) {
534 collector.enterTry(boxedOnEntry);
535 }
536 void restoreJumps(JumpCollector collector) {
537 collector.leaveTry();
538 }
539 tryBuilder.state.breakCollectors.forEach(interceptJumps);
540 tryBuilder.state.continueCollectors.forEach(interceptJumps);
541 withBuilder(tryBuilder, () {
542 visit(node.tryBlock);
543 });
544 tryBuilder.state.breakCollectors.forEach(restoreJumps);
545 tryBuilder.state.continueCollectors.forEach(restoreJumps);
546 if (tryBuilder.isOpen) {
547 for (LocalVariableElement variable in boxedOnEntry) {
548 assert(tryBuilder.isInMutableVariable(variable));
549 ir.Primitive value = tryBuilder.buildLocalGet(variable);
550 tryBuilder.environment.update(variable, value);
551 }
552 tryBuilder.jumpTo(joinContinuation);
553 }
554
555 for (LocalVariableElement variable in boxedOnEntry) {
556 assert(catchBuilder.isInMutableVariable(variable));
557 ir.Primitive value = catchBuilder.buildLocalGet(variable);
558 // Note that we remove the variable from the set of mutable variables
559 // here (and not above for the try body). This is because the set of
560 // mutable variables is global for the whole function and not local to
561 // a delimited builder.
562 catchBuilder.removeMutableVariable(variable);
563 catchBuilder.environment.update(variable, value);
564 }
565 ast.CatchBlock catchClause = node.catchBlocks.nodes.head;
566 assert(catchClause.exception != null);
567 LocalVariableElement exceptionElement = elements[catchClause.exception];
568 ir.Parameter exceptionParameter = new ir.Parameter(exceptionElement);
569 catchBuilder.environment.extend(exceptionElement, exceptionParameter);
570 ir.Parameter traceParameter;
571 if (catchClause.trace != null) {
572 LocalVariableElement traceElement = elements[catchClause.trace];
573 traceParameter = new ir.Parameter(traceElement);
574 catchBuilder.environment.extend(traceElement, traceParameter);
575 } else {
576 // Use a dummy continuation parameter for the stack trace parameter.
577 // This will ensure that all handlers have two parameters and so they
578 // can be treated uniformly.
579 traceParameter = new ir.Parameter(null);
580 }
581 withBuilder(catchBuilder, () {
582 visit(catchClause.block);
583 });
584 if (catchBuilder.isOpen) {
585 catchBuilder.jumpTo(joinContinuation);
586 }
587 List<ir.Parameter> catchParameters =
588 <ir.Parameter>[exceptionParameter, traceParameter];
589 ir.Continuation catchContinuation = new ir.Continuation(catchParameters);
590 catchContinuation.body = catchBuilder._root;
591
592 tryCatchBuilder.add(new ir.LetHandler(catchContinuation, tryBuilder._root));
593 tryCatchBuilder._current = null;
594
595 irBuilder.add(new ir.LetCont(joinContinuation, tryCatchBuilder._root));
596 for (int i = 0; i < irBuilder.environment.length; ++i) {
597 irBuilder.environment.index2value[i] = joinParameters[i];
598 }
599 return null;
600 } 493 }
601 494
602 // ==== Expressions ==== 495 // ==== Expressions ====
603 ir.Primitive visitConditional(ast.Conditional node) { 496 ir.Primitive visitConditional(ast.Conditional node) {
604 return irBuilder.buildConditional( 497 return irBuilder.buildConditional(
605 build(node.condition), 498 build(node.condition),
606 subbuild(node.thenExpression), 499 subbuild(node.thenExpression),
607 subbuild(node.elseExpression)); 500 subbuild(node.elseExpression));
608 } 501 }
609 502
(...skipping 1331 matching lines...) Expand 10 before | Expand all | Expand 10 after
1941 SourceInformation buildCall(ast.Node node) { 1834 SourceInformation buildCall(ast.Node node) {
1942 return new PositionSourceInformation( 1835 return new PositionSourceInformation(
1943 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); 1836 new TokenSourceLocation(sourceFile, node.getBeginToken(), name));
1944 } 1837 }
1945 1838
1946 @override 1839 @override
1947 SourceInformationBuilder forContext(AstElement element) { 1840 SourceInformationBuilder forContext(AstElement element) {
1948 return new PositionSourceInformationBuilder(element); 1841 return new PositionSourceInformationBuilder(element);
1949 } 1842 }
1950 } 1843 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698