Chromium Code Reviews| OLD | NEW |
|---|---|
| 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'; |
| 11 import '../elements/elements.dart'; | 11 import '../elements/elements.dart'; |
| 12 import '../io/source_file.dart'; | |
| 13 import '../tree/tree.dart' as ast; | 12 import '../tree/tree.dart' as ast; |
| 14 import '../scanner/scannerlib.dart' show Token, isUserDefinableOperator; | |
| 15 import '../universe/universe.dart' show SelectorKind; | |
| 16 import 'cps_ir_nodes.dart' as ir; | 13 import 'cps_ir_nodes.dart' as ir; |
| 17 import '../elements/modelx.dart' show SynthesizedConstructorElementX, | |
| 18 ConstructorBodyElementX, FunctionSignatureX; | |
| 19 import '../closure.dart' hide ClosureScope; | 14 import '../closure.dart' hide ClosureScope; |
| 20 import '../closure.dart' as closurelib; | |
| 21 import '../js_backend/js_backend.dart' show JavaScriptBackend; | |
| 22 | |
| 23 part 'cps_ir_builder_visitor.dart'; | |
| 24 | 15 |
| 25 /// A mapping from variable elements to their compile-time values. | 16 /// A mapping from variable elements to their compile-time values. |
| 26 /// | 17 /// |
| 27 /// Map elements denoted by parameters and local variables to the | 18 /// Map elements denoted by parameters and local variables to the |
| 28 /// [ir.Primitive] that is their value. Parameters and locals are | 19 /// [ir.Primitive] that is their value. Parameters and locals are |
| 29 /// assigned indexes which can be used to refer to them. | 20 /// assigned indexes which can be used to refer to them. |
| 30 class Environment { | 21 class Environment { |
| 31 /// A map from locals to their environment index. | 22 /// A map from locals to their environment index. |
| 32 final Map<Local, int> variable2index; | 23 final Map<Local, int> variable2index; |
| 33 | 24 |
| (...skipping 1203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1237 // TODO(johnniwinther): Type [nodes] as `Iterable` when `NodeList` uses | 1228 // TODO(johnniwinther): Type [nodes] as `Iterable` when `NodeList` uses |
| 1238 // `List` instead of `Link`. | 1229 // `List` instead of `Link`. |
| 1239 void buildSequence(var nodes, BuildFunction build) { | 1230 void buildSequence(var nodes, BuildFunction build) { |
| 1240 for (var node in nodes) { | 1231 for (var node in nodes) { |
| 1241 if (!isOpen) return; | 1232 if (!isOpen) return; |
| 1242 build(node); | 1233 build(node); |
| 1243 } | 1234 } |
| 1244 } | 1235 } |
| 1245 | 1236 |
| 1246 | 1237 |
| 1238 /// Creates a labeled statement | |
| 1239 void buildLabeledStatement({SubbuildFunction buildBody, | |
| 1240 JumpTarget target}) { | |
| 1241 JumpCollector jumps = new JumpCollector(target); | |
| 1242 state.breakCollectors.add(jumps); | |
| 1243 IrBuilder innerBuilder = makeDelimitedBuilder(); | |
| 1244 buildBody(innerBuilder); | |
| 1245 state.breakCollectors.removeLast(); | |
| 1246 bool hasBreaks = !jumps.isEmpty; | |
| 1247 ir.Continuation joinContinuation; | |
| 1248 if (hasBreaks) { | |
| 1249 if (innerBuilder.isOpen) { | |
| 1250 jumps.addJump(innerBuilder); | |
| 1251 } | |
| 1252 | |
| 1253 // All jumps to the break continuation must be in the scope of the | |
| 1254 // continuation's binding. The continuation is bound just outside the | |
| 1255 // body to satisfy this property without extra analysis. | |
| 1256 // As a consequence, the break continuation needs parameters for all | |
| 1257 // local variables in scope at the exit from the body. | |
| 1258 List<ir.Parameter> parameters = | |
| 1259 new List<ir.Parameter>.generate(environment.length, (i) { | |
| 1260 return new ir.Parameter(environment.index2variable[i]); | |
| 1261 }); | |
| 1262 joinContinuation = new ir.Continuation(parameters); | |
| 1263 invokeFullJoin(joinContinuation, jumps, recursive: false); | |
| 1264 add(new ir.LetCont(joinContinuation, innerBuilder._root)); | |
| 1265 for (int i = 0; i < environment.length; ++i) { | |
| 1266 environment.index2value[i] = parameters[i]; | |
| 1267 } | |
| 1268 } else { | |
| 1269 if (innerBuilder._root != null) { | |
| 1270 add(innerBuilder._root); | |
| 1271 _current = innerBuilder._current; | |
| 1272 environment = innerBuilder.environment; | |
| 1273 } | |
| 1274 } | |
| 1275 return null; | |
| 1276 } | |
| 1277 | |
| 1278 | |
| 1247 // Build(BreakStatement L, C) = C[InvokeContinuation(...)] | 1279 // Build(BreakStatement L, C) = C[InvokeContinuation(...)] |
| 1248 // | 1280 // |
| 1249 // The continuation and arguments are filled in later after translating | 1281 // The continuation and arguments are filled in later after translating |
| 1250 // the body containing the break. | 1282 // the body containing the break. |
| 1251 bool buildBreak(JumpTarget target) { | 1283 bool buildBreak(JumpTarget target) { |
| 1252 return buildJumpInternal(target, state.breakCollectors); | 1284 return buildJumpInternal(target, state.breakCollectors); |
| 1253 } | 1285 } |
| 1254 | 1286 |
| 1255 // Build(ContinueStatement L, C) = C[InvokeContinuation(...)] | 1287 // Build(ContinueStatement L, C) = C[InvokeContinuation(...)] |
| 1256 // | 1288 // |
| (...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1761 if (env.thisLocal != null && env.freeVariables.containsKey(env.thisLocal)) { | 1793 if (env.thisLocal != null && env.freeVariables.containsKey(env.thisLocal)) { |
| 1762 jsState.receiver = environment.lookup(env.thisLocal); | 1794 jsState.receiver = environment.lookup(env.thisLocal); |
| 1763 } | 1795 } |
| 1764 | 1796 |
| 1765 // If the function has a self-reference, use the value of `this`. | 1797 // If the function has a self-reference, use the value of `this`. |
| 1766 if (env.selfReference != null) { | 1798 if (env.selfReference != null) { |
| 1767 environment.extend(env.selfReference, thisPrim); | 1799 environment.extend(env.selfReference, thisPrim); |
| 1768 } | 1800 } |
| 1769 } | 1801 } |
| 1770 | 1802 |
| 1803 // TODO(johnniwinther,asgerf): Should this be public? Currently needed by | |
| 1804 // [JsIrBuilderVisitor.loadArguments]. | |
|
asgerf
2015/02/11 10:51:14
I'd say ditch the TODO and just document what the
Johnni Winther
2015/03/05 11:05:53
Done.
| |
| 1805 void enterScope(ClosureScope scope) => _enterScope(scope); | |
| 1806 | |
| 1771 void _enterScope(ClosureScope scope) { | 1807 void _enterScope(ClosureScope scope) { |
| 1772 if (scope == null) return; | 1808 if (scope == null) return; |
| 1773 ir.CreateBox boxPrim = new ir.CreateBox(); | 1809 ir.CreateBox boxPrim = new ir.CreateBox(); |
| 1774 add(new ir.LetPrim(boxPrim)); | 1810 add(new ir.LetPrim(boxPrim)); |
| 1775 environment.extend(scope.box, boxPrim); | 1811 environment.extend(scope.box, boxPrim); |
| 1776 boxPrim.useElementAsHint(scope.box); | 1812 boxPrim.useElementAsHint(scope.box); |
| 1777 scope.capturedVariables.forEach((Local local, ClosureLocation location) { | 1813 scope.capturedVariables.forEach((Local local, ClosureLocation location) { |
| 1778 assert(!jsState.boxedVariables.containsKey(local)); | 1814 assert(!jsState.boxedVariables.containsKey(local)); |
| 1779 if (location.isBox) { | 1815 if (location.isBox) { |
| 1780 jsState.boxedVariables[local] = location; | 1816 jsState.boxedVariables[local] = location; |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2008 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); | 2044 ClosureEnvironment(this.selfReference, this.thisLocal, this.freeVariables); |
| 2009 } | 2045 } |
| 2010 | 2046 |
| 2011 /// Information about which variables are captured by a nested function. | 2047 /// Information about which variables are captured by a nested function. |
| 2012 /// | 2048 /// |
| 2013 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and | 2049 /// This is used by the [DartIrBuilder] instead of [ClosureScope] and |
| 2014 /// [ClosureEnvironment]. | 2050 /// [ClosureEnvironment]. |
| 2015 abstract class DartCapturedVariableInfo { | 2051 abstract class DartCapturedVariableInfo { |
| 2016 Iterable<Local> get capturedVariables; | 2052 Iterable<Local> get capturedVariables; |
| 2017 } | 2053 } |
| OLD | NEW |