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

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