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_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 2479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2490 | 2490 |
| 2491 JsIrBuilder getBuilderFor(Element element) { | 2491 JsIrBuilder getBuilderFor(Element element) { |
| 2492 return new JsIrBuilder( | 2492 return new JsIrBuilder( |
| 2493 new GlobalProgramInformation(compiler), | 2493 new GlobalProgramInformation(compiler), |
| 2494 compiler.backend.constantSystem, | 2494 compiler.backend.constantSystem, |
| 2495 element); | 2495 element); |
| 2496 } | 2496 } |
| 2497 | 2497 |
| 2498 /// Builds the IR for a given constructor. | 2498 /// Builds the IR for a given constructor. |
| 2499 /// | 2499 /// |
| 2500 /// 1. Evaluates all own or inherited field initializers. | 2500 /// 1. Builds all types held in own or "inherited" type variables. |
|
karlklose
2015/05/28 08:12:19
Not sure what 'builds' means here. Further down we
asgerf
2015/05/28 09:34:21
I've tried to clarify a bit.
| |
| 2501 /// 2. Creates the object and assigns its fields. | 2501 /// 2. Evaluates all own or inherited field initializers. |
| 2502 /// 3. Calls constructor body and super constructor bodies. | 2502 /// 3. Creates the object and assigns its fields. |
| 2503 /// 4. Returns the created object. | 2503 /// 4. Calls constructor body and super constructor bodies. |
| 2504 /// 5. Returns the created object. | |
| 2504 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { | 2505 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { |
| 2505 // TODO(asgerf): Optimization: If constructor is redirecting, then just | 2506 // TODO(asgerf): Optimization: If constructor is redirecting, then just |
| 2506 // evaluate arguments and call the target constructor. | 2507 // evaluate arguments and call the target constructor. |
| 2507 constructor = constructor.implementation; | 2508 constructor = constructor.implementation; |
| 2508 ClassElement classElement = constructor.enclosingClass.implementation; | 2509 ClassElement classElement = constructor.enclosingClass.implementation; |
| 2509 | 2510 |
| 2510 JsIrBuilder builder = getBuilderFor(constructor); | 2511 JsIrBuilder builder = getBuilderFor(constructor); |
| 2511 | 2512 |
| 2512 final bool requiresTypeInformation = | 2513 final bool requiresTypeInformation = |
| 2513 builder.program.requiresRuntimeTypesFor(classElement); | 2514 builder.program.requiresRuntimeTypesFor(classElement); |
| 2514 | 2515 |
| 2515 return withBuilder(builder, () { | 2516 return withBuilder(builder, () { |
| 2516 // Setup parameters and create a box if anything is captured. | 2517 // Setup parameters and create a box if anything is captured. |
| 2517 List<Local> parameters = <Local>[]; | 2518 List<Local> parameters = <Local>[]; |
| 2518 constructor.functionSignature.orderedForEachParameter( | 2519 constructor.functionSignature.orderedForEachParameter( |
| 2519 (ParameterElement p) => parameters.add(p)); | 2520 (ParameterElement p) => parameters.add(p)); |
| 2520 | 2521 |
| 2521 int firstTypeArgumentParameterIndex; | 2522 int firstTypeArgumentParameterIndex; |
| 2522 | 2523 |
| 2523 // If instances of the class may need runtime type information, we add a | 2524 // If instances of the class may need runtime type information, we add a |
| 2524 // synthetic parameter for each type parameter. | 2525 // synthetic parameter for each type parameter. |
| 2525 if (requiresTypeInformation) { | 2526 if (requiresTypeInformation) { |
| 2526 firstTypeArgumentParameterIndex = parameters.length; | 2527 firstTypeArgumentParameterIndex = parameters.length; |
| 2527 classElement.typeVariables.forEach((TypeVariableType variable) { | 2528 classElement.typeVariables.forEach((TypeVariableType variable) { |
| 2528 parameters.add( | 2529 parameters.add(new TypeVariableLocal(variable, constructor)); |
| 2529 new TypeInformationParameter(variable.element, constructor)); | 2530 }); |
| 2531 } else { | |
| 2532 classElement.typeVariables.forEach((TypeVariableType variable) { | |
| 2533 irBuilder.declareTypeVariable(variable, const DynamicType()); | |
| 2530 }); | 2534 }); |
| 2531 } | 2535 } |
| 2532 | 2536 |
| 2533 // Create IR parameters and setup the environment. | 2537 // Create IR parameters and setup the environment. |
| 2534 List<ir.Parameter> irParameters = builder.buildFunctionHeader(parameters, | 2538 List<ir.Parameter> irParameters = builder.buildFunctionHeader(parameters, |
| 2535 closureScope: getClosureScopeForFunction(constructor)); | 2539 closureScope: getClosureScopeForFunction(constructor)); |
| 2536 | 2540 |
| 2537 // Create a list of the values of all type argument parameters, if any. | 2541 // Create a list of the values of all type argument parameters, if any. |
| 2538 List<ir.Primitive> typeInformation; | 2542 List<ir.Primitive> typeInformation; |
| 2539 if (requiresTypeInformation) { | 2543 if (requiresTypeInformation) { |
| 2540 typeInformation = irParameters.sublist(firstTypeArgumentParameterIndex); | 2544 typeInformation = irParameters.sublist(firstTypeArgumentParameterIndex); |
| 2541 } else { | 2545 } else { |
| 2542 typeInformation = const <ir.Primitive>[]; | 2546 typeInformation = const <ir.Primitive>[]; |
| 2543 } | 2547 } |
| 2544 | 2548 |
| 2545 // -- Step 1: evaluate field initializers --- | 2549 // -- Load values for type variables declared on super classes -- |
| 2550 // Field initializers for super classes can reference these, so they | |
| 2551 // must be available before evaluating field initializers. | |
| 2552 // This could be interleaved with field initialization, but we choose do | |
| 2553 // get it out of the way here to avoid complications with mixins. | |
| 2554 loadTypeVariablesForSuperClasses(classElement); | |
| 2555 | |
| 2556 // -- Evaluate field initializers --- | |
| 2546 // Evaluate field initializers in constructor and super constructors. | 2557 // Evaluate field initializers in constructor and super constructors. |
| 2547 irBuilder.enterInitializers(); | 2558 irBuilder.enterInitializers(); |
| 2548 List<ConstructorElement> constructorList = <ConstructorElement>[]; | 2559 List<ConstructorElement> constructorList = <ConstructorElement>[]; |
| 2549 evaluateConstructorFieldInitializers(constructor, constructorList); | 2560 evaluateConstructorFieldInitializers(constructor, constructorList); |
| 2550 irBuilder.leaveInitializers(); | 2561 irBuilder.leaveInitializers(); |
| 2551 | 2562 |
| 2552 // All parameters in all constructors are now bound in the environment. | 2563 // All parameters in all constructors are now bound in the environment. |
| 2553 // BoxLocals for captured parameters are also in the environment. | 2564 // BoxLocals for captured parameters are also in the environment. |
| 2554 // The initial value of all fields are now bound in [fieldValues]. | 2565 // The initial value of all fields are now bound in [fieldValues]. |
| 2555 | 2566 |
| 2556 // --- Step 2: create the object --- | 2567 // --- Create the object --- |
| 2557 // Get the initial field values in the canonical order. | 2568 // Get the initial field values in the canonical order. |
| 2558 List<ir.Primitive> instanceArguments = <ir.Primitive>[]; | 2569 List<ir.Primitive> instanceArguments = <ir.Primitive>[]; |
| 2559 classElement.forEachInstanceField((ClassElement c, FieldElement field) { | 2570 classElement.forEachInstanceField((ClassElement c, FieldElement field) { |
| 2560 ir.Primitive value = fieldValues[field]; | 2571 ir.Primitive value = fieldValues[field]; |
| 2561 if (value != null) { | 2572 if (value != null) { |
| 2562 instanceArguments.add(value); | 2573 instanceArguments.add(value); |
| 2563 } else { | 2574 } else { |
| 2564 assert(Elements.isNativeOrExtendsNative(c)); | 2575 assert(Elements.isNativeOrExtendsNative(c)); |
| 2565 // Native fields are initialized elsewhere. | 2576 // Native fields are initialized elsewhere. |
| 2566 } | 2577 } |
| 2567 }, includeSuperAndInjectedMembers: true); | 2578 }, includeSuperAndInjectedMembers: true); |
| 2568 ir.Primitive instance = new ir.CreateInstance( | 2579 ir.Primitive instance = new ir.CreateInstance( |
| 2569 classElement, | 2580 classElement, |
| 2570 instanceArguments, | 2581 instanceArguments, |
| 2571 typeInformation); | 2582 typeInformation); |
| 2572 irBuilder.add(new ir.LetPrim(instance)); | 2583 irBuilder.add(new ir.LetPrim(instance)); |
| 2573 | 2584 |
| 2574 // --- Step 3: call constructor bodies --- | 2585 // --- Call constructor bodies --- |
| 2575 for (ConstructorElement target in constructorList) { | 2586 for (ConstructorElement target in constructorList) { |
| 2576 ConstructorBodyElement bodyElement = getConstructorBody(target); | 2587 ConstructorBodyElement bodyElement = getConstructorBody(target); |
| 2577 if (bodyElement == null) continue; // Skip if constructor has no body. | 2588 if (bodyElement == null) continue; // Skip if constructor has no body. |
| 2578 List<ir.Primitive> bodyArguments = <ir.Primitive>[]; | 2589 List<ir.Primitive> bodyArguments = <ir.Primitive>[]; |
| 2579 for (Local param in getConstructorBodyParameters(bodyElement)) { | 2590 for (Local param in getConstructorBodyParameters(bodyElement)) { |
| 2580 bodyArguments.add(irBuilder.environment.lookup(param)); | 2591 bodyArguments.add(irBuilder.environment.lookup(param)); |
| 2581 } | 2592 } |
| 2582 irBuilder.buildInvokeDirectly(bodyElement, instance, bodyArguments); | 2593 irBuilder.buildInvokeDirectly(bodyElement, instance, bodyArguments); |
| 2583 } | 2594 } |
| 2584 | 2595 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2666 FunctionElement target = superClass.lookupDefaultConstructor(); | 2677 FunctionElement target = superClass.lookupDefaultConstructor(); |
| 2667 if (target == null) { | 2678 if (target == null) { |
| 2668 compiler.internalError(superClass, "No default constructor available."); | 2679 compiler.internalError(superClass, "No default constructor available."); |
| 2669 } | 2680 } |
| 2670 evaluateConstructorFieldInitializers(target, supers); | 2681 evaluateConstructorFieldInitializers(target, supers); |
| 2671 } | 2682 } |
| 2672 // Add this constructor after the superconstructors. | 2683 // Add this constructor after the superconstructors. |
| 2673 supers.add(constructor); | 2684 supers.add(constructor); |
| 2674 } | 2685 } |
| 2675 | 2686 |
| 2687 /// Loads the type variables for all super classes of [superClass] into the | |
| 2688 /// IR builder's environment with their corresponding values. | |
| 2689 /// | |
| 2690 /// The type variables for [currentClass] must already be in the IR builder's | |
| 2691 /// environment. | |
| 2692 /// | |
| 2693 /// Type variables are stored as [TypeVariableLocal] in the environment. | |
| 2694 /// | |
| 2695 /// This ensures that access to type variables mentioned inside the | |
| 2696 /// constructors and initializers will happen through the local environment | |
| 2697 /// instead of using 'this'. | |
| 2698 void loadTypeVariablesForSuperClasses(ClassElement currentClass) { | |
| 2699 if (currentClass.isObject) return; | |
| 2700 loadTypeVariablesForType(currentClass.supertype); | |
| 2701 if (currentClass is MixinApplicationElement) { | |
| 2702 loadTypeVariablesForType(currentClass.mixinType); | |
| 2703 } | |
| 2704 } | |
| 2705 | |
| 2706 /// Loads all type variables for [superType] and all of its super classes into | |
| 2707 /// the environment. All type variables mentioned in [superType] must already | |
| 2708 /// be in the environment. | |
| 2709 void loadTypeVariablesForType(InterfaceType type) { | |
| 2710 ClassElement clazz = type.element; | |
| 2711 assert(clazz.typeVariables.length == type.typeArguments.length); | |
| 2712 for (int i = 0; i < clazz.typeVariables.length; ++i) { | |
| 2713 TypeVariableType typeParameter = clazz.typeVariables[i]; | |
|
karlklose
2015/05/28 08:12:19
Maybe inline typeParameter and typeArgument.
asgerf
2015/05/28 09:34:21
Done.
| |
| 2714 DartType typeArgument = type.typeArguments[i]; | |
| 2715 irBuilder.declareTypeVariable(typeParameter, typeArgument); | |
| 2716 } | |
| 2717 loadTypeVariablesForSuperClasses(clazz); | |
| 2718 } | |
| 2719 | |
| 2676 /// In preparation of inlining (part of) [target], the [arguments] are moved | 2720 /// In preparation of inlining (part of) [target], the [arguments] are moved |
| 2677 /// into the environment bindings for the corresponding parameters. | 2721 /// into the environment bindings for the corresponding parameters. |
| 2678 /// | 2722 /// |
| 2679 /// Defaults for optional arguments are evaluated in order to ensure | 2723 /// Defaults for optional arguments are evaluated in order to ensure |
| 2680 /// all parameters are available in the environment. | 2724 /// all parameters are available in the environment. |
| 2681 void loadArguments(FunctionElement target, | 2725 void loadArguments(ConstructorElement target, |
| 2682 Selector selector, | 2726 Selector selector, |
| 2683 List<ir.Primitive> arguments) { | 2727 List<ir.Primitive> arguments) { |
| 2684 target = target.implementation; | 2728 target = target.implementation; |
| 2685 FunctionSignature signature = target.functionSignature; | 2729 FunctionSignature signature = target.functionSignature; |
| 2686 | 2730 |
| 2687 // Establish a scope in case parameters are captured. | 2731 // Establish a scope in case parameters are captured. |
| 2688 ClosureScope scope = getClosureScopeForFunction(target); | 2732 ClosureScope scope = getClosureScopeForFunction(target); |
| 2689 irBuilder.enterScope(scope); | 2733 irBuilder.enterScope(scope); |
| 2690 | 2734 |
| 2691 // Load required parameters | 2735 // Load required parameters |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3075 node.body = replacementFor(node.body); | 3119 node.body = replacementFor(node.body); |
| 3076 } | 3120 } |
| 3077 } | 3121 } |
| 3078 | 3122 |
| 3079 /// Visit a just-deleted subterm and unlink all [Reference]s in it. | 3123 /// Visit a just-deleted subterm and unlink all [Reference]s in it. |
| 3080 class RemovalVisitor extends ir.RecursiveVisitor { | 3124 class RemovalVisitor extends ir.RecursiveVisitor { |
| 3081 processReference(ir.Reference reference) { | 3125 processReference(ir.Reference reference) { |
| 3082 reference.unlink(); | 3126 reference.unlink(); |
| 3083 } | 3127 } |
| 3084 } | 3128 } |
| OLD | NEW |