Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(299)

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart

Issue 1158693003: dart2js cps: Change how type variables are accessed in constructors. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698