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

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

Issue 1080003005: Make the mutable variables local to an IR builder instead of global. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: A pair of bug fixes. Created 5 years, 8 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 | « no previous file | 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 library dart2js.ir_builder; 5 library dart2js.ir_builder;
6 6
7 import '../constants/constant_system.dart'; 7 import '../constants/constant_system.dart';
8 import '../constants/expressions.dart'; 8 import '../constants/expressions.dart';
9 import '../constants/values.dart' show PrimitiveConstantValue; 9 import '../constants/values.dart' show PrimitiveConstantValue;
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 // TODO(johnniwinther): Type [nodes] as `Iterable<N>` when `NodeList` uses 369 // TODO(johnniwinther): Type [nodes] as `Iterable<N>` when `NodeList` uses
370 // `List` instead of `Link`. 370 // `List` instead of `Link`.
371 SubbuildFunction subbuildSequence(/*Iterable<N>*/ nodes) { 371 SubbuildFunction subbuildSequence(/*Iterable<N>*/ nodes) {
372 return (IrBuilder builder) { 372 return (IrBuilder builder) {
373 return withBuilder(builder, () => builder.buildSequence(nodes, build)); 373 return withBuilder(builder, () => builder.buildSequence(nodes, build));
374 }; 374 };
375 } 375 }
376 } 376 }
377 377
378 /// Shared state between delimited IrBuilders within the same function. 378 /// Shared state between delimited IrBuilders within the same function.
379 class IrBuilderDelimitedState { 379 class IrBuilderSharedState {
380 final ConstantSystem constantSystem; 380 final ConstantSystem constantSystem;
381 381
382 /// A stack of collectors for breaks. 382 /// A stack of collectors for breaks.
383 final List<JumpCollector> breakCollectors = <JumpCollector>[]; 383 final List<JumpCollector> breakCollectors = <JumpCollector>[];
384 384
385 /// A stack of collectors for continues. 385 /// A stack of collectors for continues.
386 final List<JumpCollector> continueCollectors = <JumpCollector>[]; 386 final List<JumpCollector> continueCollectors = <JumpCollector>[];
387 387
388 final List<ConstDeclaration> localConstants = <ConstDeclaration>[]; 388 final List<ConstDeclaration> localConstants = <ConstDeclaration>[];
389 389
390 final ExecutableElement currentElement; 390 final ExecutableElement currentElement;
391 391
392 final ir.Continuation returnContinuation = new ir.Continuation.retrn(); 392 final ir.Continuation returnContinuation = new ir.Continuation.retrn();
393 ir.Parameter _thisParameter; 393 ir.Parameter _thisParameter;
394 ir.Parameter enclosingMethodThisParameter; 394 ir.Parameter enclosingMethodThisParameter;
395 395
396 final List<ir.Definition> functionParameters = <ir.Definition>[]; 396 final List<ir.Definition> functionParameters = <ir.Definition>[];
397 397
398 IrBuilderDelimitedState(this.constantSystem, this.currentElement); 398 IrBuilderSharedState(this.constantSystem, this.currentElement);
399 399
400 ir.Parameter get thisParameter => _thisParameter; 400 ir.Parameter get thisParameter => _thisParameter;
401 void set thisParameter(ir.Parameter value) { 401 void set thisParameter(ir.Parameter value) {
402 assert(_thisParameter == null); 402 assert(_thisParameter == null);
403 _thisParameter = value; 403 _thisParameter = value;
404 } 404 }
405 } 405 }
406 406
407 class ThisParameterLocal implements Local { 407 class ThisParameterLocal implements Local {
408 final ExecutableElement executableContext; 408 final ExecutableElement executableContext;
409 ThisParameterLocal(this.executableContext); 409 ThisParameterLocal(this.executableContext);
410 String get name => 'this'; 410 String get name => 'this';
411 toString() => 'ThisParameterLocal($executableContext)'; 411 toString() => 'ThisParameterLocal($executableContext)';
412 } 412 }
413 413
414 /// A factory for building the cps IR. 414 /// A factory for building the cps IR.
415 /// 415 ///
416 /// [DartIrBuilder] and [JsIrBuilder] implement nested functions and captured 416 /// [DartIrBuilder] and [JsIrBuilder] implement nested functions and captured
417 /// variables in different ways. 417 /// variables in different ways.
418 abstract class IrBuilder { 418 abstract class IrBuilder {
419 IrBuilder _makeInstance(); 419 IrBuilder _makeInstance();
420 420
421 /// True if [local] should currently be accessed from a [ir.MutableVariable].
422 bool isInMutableVariable(Local local);
423
424 /// Creates a [ir.MutableVariable] for the given local.
425 void makeMutableVariable(Local local);
426
427 /// Remove an [ir.MutableVariable] for a local.
428 ///
429 /// Subsequent access to the local will be direct rather than through the
430 /// mutable variable. This is used for variables that do not spend their
431 /// entire lifetime as mutable variables (e.g., variables that are boxed
432 /// in mutable variables for a try block).
433 void removeMutableVariable(Local local);
434
435 void declareLocalVariable(LocalVariableElement element, 421 void declareLocalVariable(LocalVariableElement element,
436 {ir.Primitive initialValue}); 422 {ir.Primitive initialValue});
437 423
438 /// Called when entering a nested function with free variables. 424 /// Called when entering a nested function with free variables.
439 /// 425 ///
440 /// The free variables must subsequently be accessible using [buildLocalGet] 426 /// The free variables must subsequently be accessible using [buildLocalGet]
441 /// and [buildLocalSet]. 427 /// and [buildLocalSet].
442 void _enterClosureEnvironment(ClosureEnvironment env); 428 void _enterClosureEnvironment(ClosureEnvironment env);
443 429
444 /// Called when entering a function body or loop body. 430 /// Called when entering a function body or loop body.
(...skipping 30 matching lines...) Expand all
475 /// 461 ///
476 /// If inside a closure class, [buildThis] will redirect access through 462 /// If inside a closure class, [buildThis] will redirect access through
477 /// closure fields in order to access the receiver from the enclosing method. 463 /// closure fields in order to access the receiver from the enclosing method.
478 ir.Primitive buildThis(); 464 ir.Primitive buildThis();
479 465
480 // TODO(johnniwinther): Make these field final and remove the default values 466 // TODO(johnniwinther): Make these field final and remove the default values
481 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin. 467 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin.
482 468
483 final List<ir.Parameter> _parameters = <ir.Parameter>[]; 469 final List<ir.Parameter> _parameters = <ir.Parameter>[];
484 470
485 IrBuilderDelimitedState state; 471 IrBuilderSharedState state;
486 472
487 /// A map from variable indexes to their values. 473 /// A map from variable indexes to their values.
488 /// 474 ///
489 /// [BoxLocal]s map to their box. [LocalElement]s that are boxed are not 475 /// [BoxLocal]s map to their box. [LocalElement]s that are boxed are not
490 /// in the map; look up their [BoxLocal] instead. 476 /// in the map; look up their [BoxLocal] instead.
491 Environment environment; 477 Environment environment;
492 478
479 /// A map from mutable local variables to their [ir.MutableVariable]s.
480 ///
481 /// Mutable variables are treated as boxed. Writes to them are observable
482 /// side effects.
483 Map<Local, ir.MutableVariable> mutableVariables;
484
485 /// True if [local] should currently be accessed from a [ir.MutableVariable].
486 bool isInMutableVariable(Local local) {
487 return mutableVariables.containsKey(local);
488 }
489
490 /// Creates a [ir.MutableVariable] for the given local.
491 void makeMutableVariable(Local local) {
492 mutableVariables[local] =
493 new ir.MutableVariable(local.executableContext, local);
494 }
495
496 /// Remove an [ir.MutableVariable] for a local.
497 ///
498 /// Subsequent access to the local will be direct rather than through the
499 /// mutable variable.
500 void removeMutableVariable(Local local) {
501 mutableVariables.remove(local);
502 }
503
504 /// Gets the [MutableVariable] containing the value of [local].
505 ir.MutableVariable getMutableVariable(Local local) {
506 return mutableVariables[local];
507 }
508
493 // The IR builder maintains a context, which is an expression with a hole in 509 // The IR builder maintains a context, which is an expression with a hole in
494 // it. The hole represents the focus where new expressions can be added. 510 // it. The hole represents the focus where new expressions can be added.
495 // The context is implemented by 'root' which is the root of the expression 511 // The context is implemented by 'root' which is the root of the expression
496 // and 'current' which is the expression that immediately contains the hole. 512 // and 'current' which is the expression that immediately contains the hole.
497 // Not all expressions have a hole (e.g., invocations, which always occur in 513 // Not all expressions have a hole (e.g., invocations, which always occur in
498 // tail position, do not have a hole). Expressions with a hole have a plug 514 // tail position, do not have a hole). Expressions with a hole have a plug
499 // method. 515 // method.
500 // 516 //
501 // Conceptually, visiting a statement takes a context as input and returns 517 // Conceptually, visiting a statement takes a context as input and returns
502 // either a new context or else an expression without a hole if all 518 // either a new context or else an expression without a hole if all
503 // control-flow paths through the statement have exited. An expression 519 // control-flow paths through the statement have exited. An expression
504 // without a hole is represented by a (root, current) pair where root is the 520 // without a hole is represented by a (root, current) pair where root is the
505 // expression and current is null. 521 // expression and current is null.
506 // 522 //
507 // Conceptually again, visiting an expression takes a context as input and 523 // Conceptually again, visiting an expression takes a context as input and
508 // returns either a pair of a new context and a definition denoting 524 // returns either a pair of a new context and a definition denoting
509 // the expression's value, or else an expression without a hole if all 525 // the expression's value, or else an expression without a hole if all
510 // control-flow paths through the expression have exited. 526 // control-flow paths through the expression have exited.
511 // 527 //
512 // We do not pass contexts as arguments or return them. Rather we use the 528 // We do not pass contexts as arguments or return them. Rather we use the
513 // current context (root, current) as the visitor state and mutate current. 529 // current context (root, current) as the visitor state and mutate current.
514 // Visiting a statement returns null; visiting an expression returns the 530 // Visiting a statement returns null; visiting an expression returns the
515 // primitive denoting its value. 531 // primitive denoting its value.
516 532
517 ir.Expression _root = null; 533 ir.Expression _root = null;
518 ir.Expression _current = null; 534 ir.Expression _current = null;
519 535
520 /// Initialize a new top-level IR builder. 536 /// Initialize a new top-level IR builder.
521 void _init(ConstantSystem constantSystem, ExecutableElement currentElement) { 537 void _init(ConstantSystem constantSystem, ExecutableElement currentElement) {
522 state = new IrBuilderDelimitedState(constantSystem, currentElement); 538 state = new IrBuilderSharedState(constantSystem, currentElement);
523 environment = new Environment.empty(); 539 environment = new Environment.empty();
540 mutableVariables = <Local, ir.MutableVariable>{};
524 } 541 }
525 542
526 /// Construct a delimited visitor for visiting a subtree. 543 /// Construct a delimited visitor for visiting a subtree.
527 /// 544 ///
528 /// Build a subterm that is not (yet) connected to the CPS term. The 545 /// Build a subterm that is not (yet) connected to the CPS term. The
529 /// delimited visitor has its own has its own context for building an IR 546 /// delimited visitor has its own has its own context for building an IR
530 /// expression, so the built expression is not plugged into the parent's 547 /// expression, so the built expression is not plugged into the parent's
531 /// context. It has its own compile-time environment mapping local 548 /// context. It has its own compile-time environment mapping local
532 /// variables to their values. If an optional environment argument is 549 /// variables to their values. If an optional environment argument is
533 /// supplied, it is used as the builder's initial environment. Otherwise 550 /// supplied, it is used as the builder's initial environment. Otherwise
534 /// the environment is initially a copy of the parent builder's environment. 551 /// the environment is initially a copy of the parent builder's environment.
535 IrBuilder makeDelimitedBuilder([Environment env = null]) { 552 IrBuilder makeDelimitedBuilder([Environment env = null]) {
536 return _makeInstance() 553 return _makeInstance()
537 ..state = state 554 ..state = state
538 ..environment = env != null ? env : new Environment.from(environment); 555 ..environment = env != null ? env : new Environment.from(environment)
556 ..mutableVariables = mutableVariables;
539 } 557 }
540 558
541 /// Construct a builder for making constructor field initializers. 559 /// Construct a builder for making constructor field initializers.
542 IrBuilder makeInitializerBuilder() { 560 IrBuilder makeInitializerBuilder() {
543 return _makeInstance() 561 return _makeInstance()
544 ..state = new IrBuilderDelimitedState(state.constantSystem, 562 ..state = new IrBuilderSharedState(state.constantSystem,
545 state.currentElement) 563 state.currentElement)
546 ..environment = new Environment.from(environment); 564 ..environment = new Environment.from(environment)
565 ..mutableVariables = mutableVariables;
547 } 566 }
548 567
549 /// Construct a builder for an inner function. 568 /// Construct a builder for an inner function.
550 IrBuilder makeInnerFunctionBuilder(ExecutableElement currentElement) { 569 IrBuilder makeInnerFunctionBuilder(ExecutableElement currentElement) {
551 IrBuilderDelimitedState innerState = 570 IrBuilderSharedState innerState =
552 new IrBuilderDelimitedState(state.constantSystem, currentElement) 571 new IrBuilderSharedState(state.constantSystem, currentElement)
553 ..enclosingMethodThisParameter = state.enclosingMethodThisParameter; 572 ..enclosingMethodThisParameter = state.enclosingMethodThisParameter;
554 return _makeInstance() 573 return _makeInstance()
555 ..state = innerState 574 ..state = innerState
556 ..environment = new Environment.empty(); 575 ..environment = new Environment.empty()
576 ..mutableVariables =
577 new Map<Local, ir.MutableVariable>.from(mutableVariables);
Kevin Millikin (Google) 2015/04/20 10:32:20 Inner function builders need to inherit the mutabl
557 } 578 }
558 579
559 bool get isOpen => _root == null || _current != null; 580 bool get isOpen => _root == null || _current != null;
560 581
561 582
562 void buildFieldInitializerHeader({ClosureScope closureScope}) { 583 void buildFieldInitializerHeader({ClosureScope closureScope}) {
563 _enterScope(closureScope); 584 _enterScope(closureScope);
564 } 585 }
565 586
566 List<ir.Primitive> buildFunctionHeader(Iterable<Local> parameters, 587 List<ir.Primitive> buildFunctionHeader(Iterable<Local> parameters,
(...skipping 1141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1708 // of mutable bindings for the variables assigned in the try. The join- 1729 // of mutable bindings for the variables assigned in the try. The join-
1709 // point continuation is not in the scope of these mutable bindings. 1730 // point continuation is not in the scope of these mutable bindings.
1710 // The tryBlock is in the scope of a binding for the catch handler. Each 1731 // The tryBlock is in the scope of a binding for the catch handler. Each
1711 // instruction (specifically, each call) in the tryBlock is in the dynamic 1732 // instruction (specifically, each call) in the tryBlock is in the dynamic
1712 // scope of the handler. The mutable bindings are dereferenced at the end 1733 // scope of the handler. The mutable bindings are dereferenced at the end
1713 // of the try block and at the beginning of the catch block, so the 1734 // of the try block and at the beginning of the catch block, so the
1714 // variables are unboxed in the catch block and at the join point. 1735 // variables are unboxed in the catch block and at the join point.
1715 JumpCollector join = new ForwardJumpCollector(environment); 1736 JumpCollector join = new ForwardJumpCollector(environment);
1716 IrBuilder tryCatchBuilder = makeDelimitedBuilder(); 1737 IrBuilder tryCatchBuilder = makeDelimitedBuilder();
1717 1738
1718 // Variables that are boxed due to being captured in a closure are boxed 1739 // Variables treated as mutable in a try are not mutable outside of it.
1719 // for their entire lifetime, and so they do not need to be boxed on 1740 // Work with a copy of the outer builder's mutable variables.
1720 // entry to any try block. They are not filtered out before this because 1741 tryCatchBuilder.mutableVariables =
1721 // we can not identify all of them in the same pass where we identify the 1742 new Map<Local, ir.MutableVariable>.from(mutableVariables);
1722 // variables assigned in the try (they may be captured by a closure after
1723 // the try statement).
1724 for (LocalVariableElement variable in tryStatementInfo.boxedOnEntry) { 1743 for (LocalVariableElement variable in tryStatementInfo.boxedOnEntry) {
1725 assert(!tryCatchBuilder.isInMutableVariable(variable)); 1744 assert(!tryCatchBuilder.isInMutableVariable(variable));
1726 ir.Primitive value = tryCatchBuilder.buildLocalVariableGet(variable); 1745 ir.Primitive value = tryCatchBuilder.buildLocalVariableGet(variable);
1727 tryCatchBuilder.makeMutableVariable(variable); 1746 tryCatchBuilder.makeMutableVariable(variable);
1728 tryCatchBuilder.declareLocalVariable(variable, initialValue: value); 1747 tryCatchBuilder.declareLocalVariable(variable, initialValue: value);
1729 } 1748 }
1730 1749
1731 IrBuilder tryBuilder = tryCatchBuilder.makeDelimitedBuilder(); 1750 IrBuilder tryBuilder = tryCatchBuilder.makeDelimitedBuilder();
1732 1751
1733 void interceptJumps(JumpCollector collector) { 1752 void interceptJumps(JumpCollector collector) {
(...skipping 10 matching lines...) Expand all
1744 tryBuilder.jumpTo(join); 1763 tryBuilder.jumpTo(join);
1745 restoreJumps(join); 1764 restoreJumps(join);
1746 } 1765 }
1747 tryBuilder.state.breakCollectors.forEach(restoreJumps); 1766 tryBuilder.state.breakCollectors.forEach(restoreJumps);
1748 tryBuilder.state.continueCollectors.forEach(restoreJumps); 1767 tryBuilder.state.continueCollectors.forEach(restoreJumps);
1749 1768
1750 IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder(); 1769 IrBuilder catchBuilder = tryCatchBuilder.makeDelimitedBuilder();
1751 for (LocalVariableElement variable in tryStatementInfo.boxedOnEntry) { 1770 for (LocalVariableElement variable in tryStatementInfo.boxedOnEntry) {
1752 assert(catchBuilder.isInMutableVariable(variable)); 1771 assert(catchBuilder.isInMutableVariable(variable));
1753 ir.Primitive value = catchBuilder.buildLocalVariableGet(variable); 1772 ir.Primitive value = catchBuilder.buildLocalVariableGet(variable);
1754 // Note that we remove the variable from the set of mutable variables 1773 // After this point, the variables that were boxed on entry to the try
1755 // here (and not above for the try body). This is because the set of 1774 // are no longer treated as mutable.
1756 // mutable variables is global for the whole function and not local to
1757 // a delimited builder.
1758 catchBuilder.removeMutableVariable(variable); 1775 catchBuilder.removeMutableVariable(variable);
1759 catchBuilder.environment.update(variable, value); 1776 catchBuilder.environment.update(variable, value);
1760 } 1777 }
1761 1778
1762 // TODO(kmillikin): Handle multiple catch clauses. 1779 // TODO(kmillikin): Handle multiple catch clauses.
1763 assert(catchClauseInfos.length == 1); 1780 assert(catchClauseInfos.length == 1);
1764 for (CatchClauseInfo catchClauseInfo in catchClauseInfos) { 1781 for (CatchClauseInfo catchClauseInfo in catchClauseInfos) {
1765 LocalVariableElement exceptionVariable = 1782 LocalVariableElement exceptionVariable =
1766 catchClauseInfo.exceptionVariable; 1783 catchClauseInfo.exceptionVariable;
1767 ir.Parameter exceptionParameter = new ir.Parameter(exceptionVariable); 1784 ir.Parameter exceptionParameter = new ir.Parameter(exceptionVariable);
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
2034 environment = join.environment; 2051 environment = join.environment;
2035 environment.discard(1); 2052 environment.discard(1);
2036 // There is always a join parameter for the result value, because it 2053 // There is always a join parameter for the result value, because it
2037 // is different on at least two paths. 2054 // is different on at least two paths.
2038 return join.continuation.parameters.last; 2055 return join.continuation.parameters.last;
2039 } 2056 }
2040 } 2057 }
2041 2058
2042 /// Shared state between DartIrBuilders within the same method. 2059 /// Shared state between DartIrBuilders within the same method.
2043 class DartIrBuilderSharedState { 2060 class DartIrBuilderSharedState {
2044 /// Maps local variables to their corresponding [MutableVariable] object.
2045 final Map<Local, ir.MutableVariable> local2mutable =
2046 <Local, ir.MutableVariable>{};
2047
2048 /// Creates a [MutableVariable] for the given local.
2049 void makeMutableVariable(Local local) {
2050 ir.MutableVariable variable =
2051 new ir.MutableVariable(local.executableContext, local);
2052 local2mutable[local] = variable;
2053 }
2054
2055 /// [MutableVariable]s that should temporarily be treated as registers. 2061 /// [MutableVariable]s that should temporarily be treated as registers.
2056 final Set<Local> registerizedMutableVariables = new Set<Local>(); 2062 final Set<Local> registerizedMutableVariables = new Set<Local>();
2057
2058 DartIrBuilderSharedState(Set<Local> capturedVariables) {
2059 capturedVariables.forEach(makeMutableVariable);
2060 }
2061 } 2063 }
2062 2064
2063 /// Dart-specific subclass of [IrBuilder]. 2065 /// Dart-specific subclass of [IrBuilder].
2064 /// 2066 ///
2065 /// Inner functions are represented by a [FunctionDefinition] with the 2067 /// Inner functions are represented by a [FunctionDefinition] with the
2066 /// IR for the inner function nested inside. 2068 /// IR for the inner function nested inside.
2067 /// 2069 ///
2068 /// Captured variables are translated to ref cells (see [MutableVariable]) 2070 /// Captured variables are translated to ref cells (see [MutableVariable])
2069 /// using [GetMutableVariable] and [SetMutableVariable]. 2071 /// using [GetMutableVariable] and [SetMutableVariable].
2070 class DartIrBuilder extends IrBuilder { 2072 class DartIrBuilder extends IrBuilder {
2071 final DartIrBuilderSharedState dartState; 2073 final DartIrBuilderSharedState dartState;
2072 2074
2073 IrBuilder _makeInstance() => new DartIrBuilder._blank(dartState); 2075 IrBuilder _makeInstance() => new DartIrBuilder._blank(dartState);
2074 DartIrBuilder._blank(this.dartState); 2076 DartIrBuilder._blank(this.dartState);
2075 2077
2076 DartIrBuilder(ConstantSystem constantSystem, 2078 DartIrBuilder(ConstantSystem constantSystem,
2077 ExecutableElement currentElement, 2079 ExecutableElement currentElement,
2078 Set<Local> capturedVariables) 2080 Set<Local> capturedVariables)
2079 : dartState = new DartIrBuilderSharedState(capturedVariables) { 2081 : dartState = new DartIrBuilderSharedState() {
Kevin Millikin (Google) 2015/04/20 10:32:20 There should be only one of these, not one per bui
2080 _init(constantSystem, currentElement); 2082 _init(constantSystem, currentElement);
2083 capturedVariables.forEach(makeMutableVariable);
2081 } 2084 }
2082 2085
2086 @override
2083 bool isInMutableVariable(Local local) { 2087 bool isInMutableVariable(Local local) {
2084 return dartState.local2mutable.containsKey(local) && 2088 return mutableVariables.containsKey(local) &&
2085 !dartState.registerizedMutableVariables.contains(local); 2089 !dartState.registerizedMutableVariables.contains(local);
2086 } 2090 }
2087 2091
2088 void makeMutableVariable(Local local) {
2089 dartState.makeMutableVariable(local);
2090 }
2091
2092 void removeMutableVariable(Local local) {
2093 dartState.local2mutable.remove(local);
2094 }
2095
2096 /// Gets the [MutableVariable] containing the value of [local].
2097 ir.MutableVariable getMutableVariable(Local local) {
2098 return dartState.local2mutable[local];
2099 }
2100
2101 void _enterScope(ClosureScope scope) { 2092 void _enterScope(ClosureScope scope) {
2102 assert(scope == null); 2093 assert(scope == null);
2103 } 2094 }
2104 2095
2105 void _enterClosureEnvironment(ClosureEnvironment env) { 2096 void _enterClosureEnvironment(ClosureEnvironment env) {
2106 assert(env == null); 2097 assert(env == null);
2107 } 2098 }
2108 2099
2109 void _enterForLoopInitializer(ClosureScope scope, 2100 void _enterForLoopInitializer(ClosureScope scope,
2110 List<LocalElement> loopVariables) { 2101 List<LocalElement> loopVariables) {
2111 assert(scope == null); 2102 assert(scope == null);
2112 for (LocalElement loopVariable in loopVariables) { 2103 for (LocalElement loopVariable in loopVariables) {
2113 if (dartState.local2mutable.containsKey(loopVariable)) { 2104 if (mutableVariables.containsKey(loopVariable)) {
2114 // Temporarily keep the loop variable in a primitive. 2105 // Temporarily keep the loop variable in a primitive.
2115 // The loop variable will be added to environment when 2106 // The loop variable will be added to environment when
2116 // [declareLocalVariable] is called. 2107 // [declareLocalVariable] is called.
2117 dartState.registerizedMutableVariables.add(loopVariable); 2108 dartState.registerizedMutableVariables.add(loopVariable);
2118 } 2109 }
2119 } 2110 }
2120 } 2111 }
2121 2112
2122 void _enterForLoopBody(ClosureScope scope, 2113 void _enterForLoopBody(ClosureScope scope,
2123 List<LocalElement> loopVariables) { 2114 List<LocalElement> loopVariables) {
2124 assert(scope == null); 2115 assert(scope == null);
2125 for (LocalElement loopVariable in loopVariables) { 2116 for (LocalElement loopVariable in loopVariables) {
2126 if (dartState.local2mutable.containsKey(loopVariable)) { 2117 if (mutableVariables.containsKey(loopVariable)) {
2127 // Move from [Primitive] into [MutableVariable]. 2118 // Move from [Primitive] into [MutableVariable].
2128 dartState.registerizedMutableVariables.remove(loopVariable); 2119 dartState.registerizedMutableVariables.remove(loopVariable);
2129 add(new ir.LetMutable(getMutableVariable(loopVariable), 2120 add(new ir.LetMutable(getMutableVariable(loopVariable),
2130 environment.lookup(loopVariable))); 2121 environment.lookup(loopVariable)));
2131 } 2122 }
2132 } 2123 }
2133 } 2124 }
2134 2125
2135 void _enterForLoopUpdate(ClosureScope scope, 2126 void _enterForLoopUpdate(ClosureScope scope,
2136 List<LocalElement> loopVariables) { 2127 List<LocalElement> loopVariables) {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
2285 2276
2286 IrBuilder _makeInstance() => new JsIrBuilder._blank(program, jsState); 2277 IrBuilder _makeInstance() => new JsIrBuilder._blank(program, jsState);
2287 JsIrBuilder._blank(this.program, this.jsState); 2278 JsIrBuilder._blank(this.program, this.jsState);
2288 2279
2289 JsIrBuilder(this.program, ConstantSystem constantSystem, 2280 JsIrBuilder(this.program, ConstantSystem constantSystem,
2290 ExecutableElement currentElement) 2281 ExecutableElement currentElement)
2291 : jsState = new JsIrBuilderSharedState() { 2282 : jsState = new JsIrBuilderSharedState() {
2292 _init(constantSystem, currentElement); 2283 _init(constantSystem, currentElement);
2293 } 2284 }
2294 2285
2295 Map<ast.TryStatement, TryStatementInfo> get tryStatements => null;
2296 Set<Local> get mutableCapturedVariables => null;
2297 bool isInMutableVariable(Local local) => false;
2298 void makeMutableVariable(Local local) {}
2299 void removeMutableVariable(Local local) {}
2300
2301 void enterInitializers() { 2286 void enterInitializers() {
2302 assert(jsState.inInitializers == false); 2287 assert(jsState.inInitializers == false);
2303 jsState.inInitializers = true; 2288 jsState.inInitializers = true;
2304 } 2289 }
2305 2290
2306 void leaveInitializers() { 2291 void leaveInitializers() {
2307 assert(jsState.inInitializers == true); 2292 assert(jsState.inInitializers == true);
2308 jsState.inInitializers = false; 2293 jsState.inInitializers = false;
2309 } 2294 }
2310 2295
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2384 {ir.Primitive initialValue}) { 2369 {ir.Primitive initialValue}) {
2385 assert(isOpen); 2370 assert(isOpen);
2386 if (initialValue == null) { 2371 if (initialValue == null) {
2387 initialValue = buildNullLiteral(); 2372 initialValue = buildNullLiteral();
2388 } 2373 }
2389 ClosureLocation location = jsState.boxedVariables[variableElement]; 2374 ClosureLocation location = jsState.boxedVariables[variableElement];
2390 if (location != null) { 2375 if (location != null) {
2391 add(new ir.SetField(environment.lookup(location.box), 2376 add(new ir.SetField(environment.lookup(location.box),
2392 location.field, 2377 location.field,
2393 initialValue)); 2378 initialValue));
2379 } else if (isInMutableVariable(variableElement)) {
2380 add(new ir.LetMutable(getMutableVariable(variableElement),
2381 initialValue));
2394 } else { 2382 } else {
2395 initialValue.useElementAsHint(variableElement); 2383 initialValue.useElementAsHint(variableElement);
2396 environment.extend(variableElement, initialValue); 2384 environment.extend(variableElement, initialValue);
2397 } 2385 }
2398 } 2386 }
2399 2387
2400 /// Add [functionElement] to the environment with provided [definition]. 2388 /// Add [functionElement] to the environment with provided [definition].
2401 void declareLocalFunction(LocalFunctionElement functionElement, 2389 void declareLocalFunction(LocalFunctionElement functionElement,
2402 ClosureClassElement classElement) { 2390 ClosureClassElement classElement) {
2403 ir.Primitive closure = buildFunctionExpression(classElement); 2391 ir.Primitive closure = buildFunctionExpression(classElement);
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
2660 } 2648 }
2661 2649
2662 /// Synthetic parameter to a JavaScript factory method that takes the type 2650 /// Synthetic parameter to a JavaScript factory method that takes the type
2663 /// argument given for the type variable [variable]. 2651 /// argument given for the type variable [variable].
2664 class TypeInformationParameter implements Local { 2652 class TypeInformationParameter implements Local {
2665 final TypeVariableElement variable; 2653 final TypeVariableElement variable;
2666 final ExecutableElement executableContext; 2654 final ExecutableElement executableContext;
2667 TypeInformationParameter(this.variable, this.executableContext); 2655 TypeInformationParameter(this.variable, this.executableContext);
2668 String get name => variable.name; 2656 String get name => variable.name;
2669 } 2657 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698