| 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_backend/dart_backend.dart' show DartBackend; | 9 import '../dart_backend/dart_backend.dart' show DartBackend; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 /// the same value at all invocation sites. | 253 /// the same value at all invocation sites. |
| 254 IrBuilder.recursive(IrBuilder parent) | 254 IrBuilder.recursive(IrBuilder parent) |
| 255 : this.state = parent.state, | 255 : this.state = parent.state, |
| 256 this.environment = new Environment.empty() { | 256 this.environment = new Environment.empty() { |
| 257 parent.environment.index2variable.forEach(createParameter); | 257 parent.environment.index2variable.forEach(createParameter); |
| 258 } | 258 } |
| 259 | 259 |
| 260 | 260 |
| 261 bool get isOpen => _root == null || _current != null; | 261 bool get isOpen => _root == null || _current != null; |
| 262 | 262 |
| 263 /// True if [element] is a local variable, local function, or parameter that |
| 264 /// is accessed from an inner function. Recursive self-references in a local |
| 265 /// function count as closure accesses. |
| 266 /// |
| 267 /// If `true`, [element] is a [LocalElement]. |
| 268 bool isClosureVariable(Element element) { |
| 269 return state.closureLocals.contains(element); |
| 270 } |
| 271 |
| 263 /// Create a parameter for [parameterElement] and add it to the current | 272 /// Create a parameter for [parameterElement] and add it to the current |
| 264 /// environment. | 273 /// environment. |
| 265 /// | 274 /// |
| 266 /// [isClosureVariable] marks whether [parameterElement] is accessed from an | 275 /// [isClosureVariable] marks whether [parameterElement] is accessed from an |
| 267 /// inner function. | 276 /// inner function. |
| 268 void createParameter(LocalElement parameterElement, | 277 void createParameter(LocalElement parameterElement) { |
| 269 {bool isClosureVariable: false}) { | |
| 270 ir.Parameter parameter = new ir.Parameter(parameterElement); | 278 ir.Parameter parameter = new ir.Parameter(parameterElement); |
| 271 _parameters.add(parameter); | 279 _parameters.add(parameter); |
| 272 if (isClosureVariable) { | 280 if (isClosureVariable(parameterElement)) { |
| 273 add(new ir.SetClosureVariable(parameterElement, parameter)); | 281 add(new ir.SetClosureVariable(parameterElement, parameter)); |
| 274 } else { | 282 } else { |
| 275 environment.extend(parameterElement, parameter); | 283 environment.extend(parameterElement, parameter); |
| 276 } | 284 } |
| 277 } | 285 } |
| 278 | 286 |
| 279 /// Add the constant [variableElement] to the environment with [value] as its | 287 /// Add the constant [variableElement] to the environment with [value] as its |
| 280 /// constant value. | 288 /// constant value. |
| 281 void declareLocalConstant(LocalVariableElement variableElement, | 289 void declareLocalConstant(LocalVariableElement variableElement, |
| 282 ConstantExpression value) { | 290 ConstantExpression value) { |
| 283 state.localConstants.add(new ConstDeclaration(variableElement, value)); | 291 state.localConstants.add(new ConstDeclaration(variableElement, value)); |
| 284 } | 292 } |
| 285 | 293 |
| 286 /// Add [variableElement] to the environment with [initialValue] as its | 294 /// Add [variableElement] to the environment with [initialValue] as its |
| 287 /// initial value. | 295 /// initial value. |
| 288 /// | 296 /// |
| 289 /// [isClosureVariable] marks whether [variableElement] is accessed from an | 297 /// [isClosureVariable] marks whether [variableElement] is accessed from an |
| 290 /// inner function. | 298 /// inner function. |
| 291 void declareLocalVariable(LocalVariableElement variableElement, | 299 void declareLocalVariable(LocalVariableElement variableElement, |
| 292 {ir.Primitive initialValue, | 300 {ir.Primitive initialValue}) { |
| 293 bool isClosureVariable: false}) { | |
| 294 assert(isOpen); | 301 assert(isOpen); |
| 295 if (initialValue == null) { | 302 if (initialValue == null) { |
| 296 // TODO(kmillikin): Consider pooling constants. | 303 // TODO(kmillikin): Consider pooling constants. |
| 297 // The initial value is null. | 304 // The initial value is null. |
| 298 initialValue = buildNullLiteral(); | 305 initialValue = buildNullLiteral(); |
| 299 } | 306 } |
| 300 if (isClosureVariable) { | 307 if (isClosureVariable(variableElement)) { |
| 301 add(new ir.SetClosureVariable(variableElement, | 308 add(new ir.SetClosureVariable(variableElement, |
| 302 initialValue, | 309 initialValue, |
| 303 isDeclaration: true)); | 310 isDeclaration: true)); |
| 304 } else { | 311 } else { |
| 305 // In case a primitive was introduced for the initializer expression, | 312 // In case a primitive was introduced for the initializer expression, |
| 306 // use this variable element to help derive a good name for it. | 313 // use this variable element to help derive a good name for it. |
| 307 initialValue.useElementAsHint(variableElement); | 314 initialValue.useElementAsHint(variableElement); |
| 308 environment.extend(variableElement, initialValue); | 315 environment.extend(variableElement, initialValue); |
| 309 } | 316 } |
| 310 } | 317 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 new ir.LetCont(elseContinuation, | 420 new ir.LetCont(elseContinuation, |
| 414 new ir.Branch(new ir.IsTrue(condition), | 421 new ir.Branch(new ir.IsTrue(condition), |
| 415 thenContinuation, | 422 thenContinuation, |
| 416 elseContinuation))))); | 423 elseContinuation))))); |
| 417 return (thenValue == elseValue) | 424 return (thenValue == elseValue) |
| 418 ? thenValue | 425 ? thenValue |
| 419 : joinContinuation.parameters.last; | 426 : joinContinuation.parameters.last; |
| 420 | 427 |
| 421 } | 428 } |
| 422 | 429 |
| 423 /// Create a get access of [local]. | 430 /// Create a read access of [local]. |
| 424 ir.Primitive buildLocalGet(Element local) { | 431 ir.Primitive buildLocalGet(LocalElement local) { |
| 425 assert(isOpen); | 432 assert(isOpen); |
| 426 return environment.lookup(local); | 433 if (isClosureVariable(local)) { |
| 434 ir.Primitive result = new ir.GetClosureVariable(local); |
| 435 add(new ir.LetPrim(result)); |
| 436 return result; |
| 437 } else { |
| 438 return environment.lookup(local); |
| 439 } |
| 440 } |
| 441 |
| 442 /// Create a write access to [local]. |
| 443 ir.Primitive buildLocalSet(LocalElement local, ir.Primitive valueToStore) { |
| 444 assert(isOpen); |
| 445 if (isClosureVariable(local)) { |
| 446 add(new ir.SetClosureVariable(local, valueToStore)); |
| 447 } else { |
| 448 valueToStore.useElementAsHint(local); |
| 449 environment.update(local, valueToStore); |
| 450 } |
| 451 return valueToStore; |
| 427 } | 452 } |
| 428 | 453 |
| 429 /// Create a get access of the static [element]. | 454 /// Create a get access of the static [element]. |
| 430 ir.Primitive buildStaticGet(Element element, Selector selector) { | 455 ir.Primitive buildStaticGet(Element element, Selector selector) { |
| 431 assert(isOpen); | 456 assert(isOpen); |
| 432 assert(selector.isGetter); | 457 assert(selector.isGetter); |
| 433 return continueWithExpression( | 458 return continueWithExpression( |
| 434 (k) => new ir.InvokeStatic( | 459 (k) => new ir.InvokeStatic( |
| 435 element, selector, k, const <ir.Definition>[])); | 460 element, selector, k, const <ir.Definition>[])); |
| 436 } | 461 } |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 index = 0; | 893 index = 0; |
| 869 for (int i = 0; i < environment.length; ++i) { | 894 for (int i = 0; i < environment.length; ++i) { |
| 870 if (common[i] == null) { | 895 if (common[i] == null) { |
| 871 environment.index2value[i] = parameters[index++]; | 896 environment.index2value[i] = parameters[index++]; |
| 872 } | 897 } |
| 873 } | 898 } |
| 874 | 899 |
| 875 return join; | 900 return join; |
| 876 } | 901 } |
| 877 } | 902 } |
| OLD | NEW |