| 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_task; | 5 library dart2js.ir_builder_task; |
| 6 | 6 |
| 7 import '../closure.dart' as closurelib; | 7 import '../closure.dart' as closurelib; |
| 8 import '../closure.dart' hide ClosureScope; | 8 import '../closure.dart' hide ClosureScope; |
| 9 import '../constants/expressions.dart'; | 9 import '../constants/expressions.dart'; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 3177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3188 element); | 3188 element); |
| 3189 } | 3189 } |
| 3190 | 3190 |
| 3191 /// Builds the IR for a given constructor. | 3191 /// Builds the IR for a given constructor. |
| 3192 /// | 3192 /// |
| 3193 /// 1. Evaluates all own or inherited field initializers. | 3193 /// 1. Evaluates all own or inherited field initializers. |
| 3194 /// 2. Creates the object and assigns its fields. | 3194 /// 2. Creates the object and assigns its fields. |
| 3195 /// 3. Calls constructor body and super constructor bodies. | 3195 /// 3. Calls constructor body and super constructor bodies. |
| 3196 /// 4. Returns the created object. | 3196 /// 4. Returns the created object. |
| 3197 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { | 3197 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { |
| 3198 // TODO(asgerf): Optimization: If constructor is redirecting, then just |
| 3199 // evaluate arguments and call the target constructor. |
| 3198 constructor = constructor.implementation; | 3200 constructor = constructor.implementation; |
| 3199 ClassElement classElement = constructor.enclosingClass.implementation; | 3201 ClassElement classElement = constructor.enclosingClass.implementation; |
| 3200 | 3202 |
| 3201 JsIrBuilder builder = getBuilderFor(constructor); | 3203 JsIrBuilder builder = getBuilderFor(constructor); |
| 3202 | 3204 |
| 3203 final bool requiresTypeInformation = | 3205 final bool requiresTypeInformation = |
| 3204 builder.program.requiresRuntimeTypesFor(classElement); | 3206 builder.program.requiresRuntimeTypesFor(classElement); |
| 3205 | 3207 |
| 3206 return withBuilder(builder, () { | 3208 return withBuilder(builder, () { |
| 3207 // Setup parameters and create a box if anything is captured. | 3209 // Setup parameters and create a box if anything is captured. |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3288 /// | 3290 /// |
| 3289 /// This procedure assumes that the parameters to [constructor] are available | 3291 /// This procedure assumes that the parameters to [constructor] are available |
| 3290 /// in the IR builder's environment. | 3292 /// in the IR builder's environment. |
| 3291 /// | 3293 /// |
| 3292 /// The parameters to superconstructors are, however, assumed *not* to be in | 3294 /// The parameters to superconstructors are, however, assumed *not* to be in |
| 3293 /// the environment, but will be put there by this procedure. | 3295 /// the environment, but will be put there by this procedure. |
| 3294 /// | 3296 /// |
| 3295 /// All constructors will be added to [supers], with superconstructors first. | 3297 /// All constructors will be added to [supers], with superconstructors first. |
| 3296 void evaluateConstructorFieldInitializers(ConstructorElement constructor, | 3298 void evaluateConstructorFieldInitializers(ConstructorElement constructor, |
| 3297 List<ConstructorElement> supers) { | 3299 List<ConstructorElement> supers) { |
| 3298 // Evaluate declaration-site field initializers. | |
| 3299 ClassElement enclosingClass = constructor.enclosingClass.implementation; | 3300 ClassElement enclosingClass = constructor.enclosingClass.implementation; |
| 3300 enclosingClass.forEachInstanceField((ClassElement c, FieldElement field) { | 3301 // Evaluate declaration-site field initializers, unless this constructor |
| 3301 if (field.initializer != null) { | 3302 // redirects to another using a `this()` initializer. In that case, these |
| 3302 fieldValues[field] = inlineExpression(field, field.initializer); | 3303 // will be initialized by the effective target constructor. |
| 3303 } else { | 3304 if (!constructor.isRedirectingGenerative) { |
| 3304 if (Elements.isNativeOrExtendsNative(c)) { | 3305 enclosingClass.forEachInstanceField((ClassElement c, FieldElement field) { |
| 3305 // Native field is initialized elsewhere. | 3306 if (field.initializer != null) { |
| 3307 fieldValues[field] = inlineExpression(field, field.initializer); |
| 3306 } else { | 3308 } else { |
| 3307 // Fields without an initializer default to null. | 3309 if (Elements.isNativeOrExtendsNative(c)) { |
| 3308 // This value will be overwritten below if an initializer is found. | 3310 // Native field is initialized elsewhere. |
| 3309 fieldValues[field] = irBuilder.buildNullConstant(); | 3311 } else { |
| 3312 // Fields without an initializer default to null. |
| 3313 // This value will be overwritten below if an initializer is found. |
| 3314 fieldValues[field] = irBuilder.buildNullConstant(); |
| 3315 } |
| 3310 } | 3316 } |
| 3311 } | 3317 }); |
| 3312 }); | 3318 } |
| 3313 // Evaluate initializing parameters, e.g. `Foo(this.x)`. | 3319 // Evaluate initializing parameters, e.g. `Foo(this.x)`. |
| 3314 constructor.functionSignature.orderedForEachParameter( | 3320 constructor.functionSignature.orderedForEachParameter( |
| 3315 (ParameterElement parameter) { | 3321 (ParameterElement parameter) { |
| 3316 if (parameter.isInitializingFormal) { | 3322 if (parameter.isInitializingFormal) { |
| 3317 InitializingFormalElement fieldParameter = parameter; | 3323 InitializingFormalElement fieldParameter = parameter; |
| 3318 fieldValues[fieldParameter.fieldElement] = | 3324 fieldValues[fieldParameter.fieldElement] = |
| 3319 irBuilder.buildLocalVariableGet(parameter); | 3325 irBuilder.buildLocalVariableGet(parameter); |
| 3320 } | 3326 } |
| 3321 }); | 3327 }); |
| 3322 // Evaluate constructor initializers, e.g. `Foo() : x = 50`. | 3328 // Evaluate constructor initializers, e.g. `Foo() : x = 50`. |
| 3323 ast.FunctionExpression node = constructor.node; | 3329 ast.FunctionExpression node = constructor.node; |
| 3324 bool hasConstructorCall = false; // Has this() or super() initializer? | 3330 bool hasConstructorCall = false; // Has this() or super() initializer? |
| 3325 if (node != null && node.initializers != null) { | 3331 if (node != null && node.initializers != null) { |
| 3326 for(ast.Node initializer in node.initializers) { | 3332 for(ast.Node initializer in node.initializers) { |
| 3327 if (initializer is ast.SendSet) { | 3333 if (initializer is ast.SendSet) { |
| 3328 // Field initializer. | 3334 // Field initializer. |
| 3329 FieldElement field = elements[initializer]; | 3335 FieldElement field = elements[initializer]; |
| 3330 fieldValues[field] = | 3336 fieldValues[field] = |
| 3331 inlineExpression(constructor, initializer.arguments.head); | 3337 inlineExpression(constructor, initializer.arguments.head); |
| 3332 } else if (initializer is ast.Send) { | 3338 } else if (initializer is ast.Send) { |
| 3333 // Super or this initializer. | 3339 // Super or this initializer. |
| 3334 ConstructorElement target = elements[initializer].implementation; | 3340 ConstructorElement target = elements[initializer].implementation; |
| 3335 Selector selector = elements.getSelector(initializer); | 3341 Selector selector = elements.getSelector(initializer); |
| 3336 List<ir.Primitive> arguments = initializer.arguments.mapToList(visit); | 3342 ir.Primitive evaluateArgument(ast.Node arg) { |
| 3343 return inlineExpression(constructor, arg); |
| 3344 } |
| 3345 List<ir.Primitive> arguments = |
| 3346 initializer.arguments.mapToList(evaluateArgument); |
| 3337 loadArguments(target, selector, arguments); | 3347 loadArguments(target, selector, arguments); |
| 3338 evaluateConstructorFieldInitializers(target, supers); | 3348 evaluateConstructorFieldInitializers(target, supers); |
| 3339 hasConstructorCall = true; | 3349 hasConstructorCall = true; |
| 3340 } else { | 3350 } else { |
| 3341 compiler.internalError(initializer, | 3351 compiler.internalError(initializer, |
| 3342 "Unexpected initializer type $initializer"); | 3352 "Unexpected initializer type $initializer"); |
| 3343 } | 3353 } |
| 3344 } | 3354 } |
| 3345 } | 3355 } |
| 3346 // If no super() or this() was found, also call default superconstructor. | 3356 // If no super() or this() was found, also call default superconstructor. |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3757 node.body = replacementFor(node.body); | 3767 node.body = replacementFor(node.body); |
| 3758 } | 3768 } |
| 3759 } | 3769 } |
| 3760 | 3770 |
| 3761 /// Visit a just-deleted subterm and unlink all [Reference]s in it. | 3771 /// Visit a just-deleted subterm and unlink all [Reference]s in it. |
| 3762 class RemovalVisitor extends ir.RecursiveVisitor { | 3772 class RemovalVisitor extends ir.RecursiveVisitor { |
| 3763 processReference(ir.Reference reference) { | 3773 processReference(ir.Reference reference) { |
| 3764 reference.unlink(); | 3774 reference.unlink(); |
| 3765 } | 3775 } |
| 3766 } | 3776 } |
| OLD | NEW |