OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 kernel.transformations.closure.context; | 5 library kernel.transformations.closure.context; |
6 | 6 |
7 import '../../ast.dart' | 7 import '../../ast.dart' |
8 show | 8 show |
9 Arguments, | 9 Arguments, |
10 Class, | 10 Class, |
11 ConstructorInvocation, | |
12 Expression, | 11 Expression, |
13 ExpressionStatement, | |
14 IntLiteral, | 12 IntLiteral, |
15 InterfaceType, | |
16 MethodInvocation, | 13 MethodInvocation, |
17 Name, | 14 Name, |
18 NullLiteral, | 15 NullLiteral, |
19 PropertyGet, | 16 PropertyGet, |
20 PropertySet, | |
21 StringLiteral, | 17 StringLiteral, |
22 Throw, | 18 Throw, |
23 VariableDeclaration, | 19 VariableDeclaration, |
24 VariableGet, | 20 VariableGet, |
25 VariableSet; | 21 VariableSet; |
26 | 22 |
27 import '../../frontend/accessors.dart' | 23 import '../../frontend/accessors.dart' |
28 show Accessor, IndexAccessor, VariableAccessor; | 24 show Accessor, IndexAccessor, VariableAccessor; |
29 | 25 |
30 import 'converter.dart' show ClosureConverter; | 26 import 'converter.dart' show ClosureConverter; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 final IntLiteral size; | 111 final IntLiteral size; |
116 final List<VariableDeclaration> variables = <VariableDeclaration>[]; | 112 final List<VariableDeclaration> variables = <VariableDeclaration>[]; |
117 final Map<VariableDeclaration, Arguments> initializers = | 113 final Map<VariableDeclaration, Arguments> initializers = |
118 <VariableDeclaration, Arguments>{}; | 114 <VariableDeclaration, Arguments>{}; |
119 | 115 |
120 LocalContext._internal(this.converter, this.parent, this.self, this.size); | 116 LocalContext._internal(this.converter, this.parent, this.self, this.size); |
121 | 117 |
122 factory LocalContext(ClosureConverter converter, Context parent) { | 118 factory LocalContext(ClosureConverter converter, Context parent) { |
123 Class contextClass = converter.contextClass; | 119 Class contextClass = converter.contextClass; |
124 assert(contextClass.constructors.length == 1); | 120 assert(contextClass.constructors.length == 1); |
125 IntLiteral zero = new IntLiteral(0); | 121 converter.rewriter.insertContextDeclaration( |
126 VariableDeclaration declaration = new VariableDeclaration.forValue( | 122 contextClass, parent.expression); |
127 new ConstructorInvocation( | |
128 contextClass.constructors.first, new Arguments(<Expression>[zero])), | |
129 type: new InterfaceType(contextClass)); | |
130 declaration.name = "#context"; | |
131 converter.insert(declaration); | |
132 converter.insert(new ExpressionStatement(new PropertySet( | |
133 new VariableGet(declaration), new Name('parent'), parent.expression))); | |
134 | 123 |
135 return new LocalContext._internal(converter, parent, declaration, zero); | 124 return new LocalContext._internal(converter, parent, |
| 125 converter.rewriter.contextDeclaration, |
| 126 converter.rewriter.contextSize); |
136 } | 127 } |
137 | 128 |
138 Expression get expression => accessor.buildSimpleRead(); | 129 Expression get expression => accessor.buildSimpleRead(); |
139 | 130 |
140 Accessor get accessor => new VariableAccessor(self); | 131 Accessor get accessor => new VariableAccessor(self); |
141 | 132 |
142 void extend(VariableDeclaration variable, Expression value) { | 133 void extend(VariableDeclaration variable, Expression value) { |
143 Arguments arguments = | 134 Arguments arguments = |
144 new Arguments(<Expression>[new IntLiteral(variables.length), value]); | 135 new Arguments(<Expression>[new IntLiteral(variables.length), value]); |
145 converter.insert(new ExpressionStatement( | 136 converter.rewriter.insertExtendContext(expression, arguments); |
146 new MethodInvocation(expression, new Name('[]='), arguments))); | |
147 ++size.value; | 137 ++size.value; |
148 variables.add(variable); | 138 variables.add(variable); |
149 initializers[variable] = arguments; | 139 initializers[variable] = arguments; |
150 } | 140 } |
151 | 141 |
152 void update(VariableDeclaration variable, Expression value) { | 142 void update(VariableDeclaration variable, Expression value) { |
153 Arguments arguments = initializers[variable]; | 143 Arguments arguments = initializers[variable]; |
154 arguments.positional[1] = value; | 144 arguments.positional[1] = value; |
155 value.parent = arguments; | 145 value.parent = arguments; |
156 } | 146 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 Expression get expression { | 198 Expression get expression { |
209 return accessor?.buildSimpleRead() ?? new NullLiteral(); | 199 return accessor?.buildSimpleRead() ?? new NullLiteral(); |
210 } | 200 } |
211 | 201 |
212 void extend(VariableDeclaration variable, Expression value) { | 202 void extend(VariableDeclaration variable, Expression value) { |
213 converter.context = new LocalContext(converter, this) | 203 converter.context = new LocalContext(converter, this) |
214 ..extend(variable, value); | 204 ..extend(variable, value); |
215 } | 205 } |
216 | 206 |
217 Expression lookup(VariableDeclaration variable) { | 207 Expression lookup(VariableDeclaration variable) { |
218 var context = expression; | 208 Expression context = expression; |
219 for (var variables in variabless) { | 209 for (var variables in variabless) { |
220 var index = variables.indexOf(variable); | 210 var index = variables.indexOf(variable); |
221 if (index != -1) { | 211 if (index != -1) { |
222 return new MethodInvocation(context, new Name('[]'), | 212 return new MethodInvocation(context, new Name('[]'), |
223 new Arguments(<Expression>[new IntLiteral(index)])); | 213 new Arguments(<Expression>[new IntLiteral(index)])); |
224 } | 214 } |
225 context = new PropertyGet(context, new Name('parent')); | 215 context = new PropertyGet(context, new Name('parent')); |
226 } | 216 } |
227 throw 'Unbound NestedContext.lookup($variable)'; | 217 throw 'Unbound NestedContext.lookup($variable)'; |
228 } | 218 } |
229 | 219 |
230 Expression assign(VariableDeclaration variable, Expression value, | 220 Expression assign(VariableDeclaration variable, Expression value, |
231 {bool voidContext: false}) { | 221 {bool voidContext: false}) { |
232 var context = expression; | 222 Expression context = expression; |
233 for (var variables in variabless) { | 223 for (List<VariableDeclaration> variables in variabless) { |
234 var index = variables.indexOf(variable); | 224 var index = variables.indexOf(variable); |
235 if (index != -1) { | 225 if (index != -1) { |
236 return IndexAccessor | 226 return IndexAccessor |
237 .make(context, new IntLiteral(index), null, null) | 227 .make(context, new IntLiteral(index), null, null) |
238 .buildAssignment(value, voidContext: voidContext); | 228 .buildAssignment(value, voidContext: voidContext); |
239 } | 229 } |
240 context = new PropertyGet(context, new Name('parent')); | 230 context = new PropertyGet(context, new Name('parent')); |
241 } | 231 } |
242 throw 'Unbound NestedContext.lookup($variable)'; | 232 throw 'Unbound NestedContext.lookup($variable)'; |
243 } | 233 } |
244 | 234 |
245 Context toNestedContext([Accessor accessor]) { | 235 Context toNestedContext([Accessor accessor]) { |
246 return new NestedContext(converter, accessor ?? this.accessor, variabless); | 236 return new NestedContext(converter, accessor ?? this.accessor, variabless); |
247 } | 237 } |
248 } | 238 } |
OLD | NEW |