| 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/constant_system.dart'; | 7 import '../constants/constant_system.dart'; |
| 8 import '../constants/expressions.dart'; | 8 import '../constants/expressions.dart'; |
| 9 import '../constants/values.dart' show PrimitiveConstantValue; | 9 import '../constants/values.dart' show PrimitiveConstantValue; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 450 | 450 |
| 451 /// Called before building the update of a for-loop. | 451 /// Called before building the update of a for-loop. |
| 452 void _enterForLoopUpdate(ClosureScope scope, | 452 void _enterForLoopUpdate(ClosureScope scope, |
| 453 List<LocalElement> loopVariables); | 453 List<LocalElement> loopVariables); |
| 454 | 454 |
| 455 /// Add the given function parameter to the IR, and bind it in the environment | 455 /// Add the given function parameter to the IR, and bind it in the environment |
| 456 /// or put it in its box, if necessary. | 456 /// or put it in its box, if necessary. |
| 457 void _createFunctionParameter(Local parameterElement); | 457 void _createFunctionParameter(Local parameterElement); |
| 458 void _createThisParameter(); | 458 void _createThisParameter(); |
| 459 | 459 |
| 460 /// Reifies the value of [variable] on the current receiver object. |
| 461 ir.Primitive buildReifyTypeVariable(TypeVariableType variable); |
| 462 |
| 460 /// Creates an access to the receiver from the current (or enclosing) method. | 463 /// Creates an access to the receiver from the current (or enclosing) method. |
| 461 /// | 464 /// |
| 462 /// If inside a closure class, [buildThis] will redirect access through | 465 /// If inside a closure class, [buildThis] will redirect access through |
| 463 /// closure fields in order to access the receiver from the enclosing method. | 466 /// closure fields in order to access the receiver from the enclosing method. |
| 464 ir.Primitive buildThis(); | 467 ir.Primitive buildThis(); |
| 465 | 468 |
| 466 // TODO(johnniwinther): Make these field final and remove the default values | 469 // TODO(johnniwinther): Make these field final and remove the default values |
| 467 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin. | 470 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin. |
| 468 | 471 |
| 469 final List<ir.Parameter> _parameters = <ir.Parameter>[]; | 472 final List<ir.Parameter> _parameters = <ir.Parameter>[]; |
| (...skipping 1781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2251 CallStructure callStructure, | 2254 CallStructure callStructure, |
| 2252 DartType type, | 2255 DartType type, |
| 2253 List<ir.Primitive> arguments) { | 2256 List<ir.Primitive> arguments) { |
| 2254 assert(isOpen); | 2257 assert(isOpen); |
| 2255 Selector selector = | 2258 Selector selector = |
| 2256 new Selector(SelectorKind.CALL, element.memberName, callStructure); | 2259 new Selector(SelectorKind.CALL, element.memberName, callStructure); |
| 2257 return _continueWithExpression( | 2260 return _continueWithExpression( |
| 2258 (k) => new ir.InvokeConstructor(type, element, selector, | 2261 (k) => new ir.InvokeConstructor(type, element, selector, |
| 2259 arguments, k)); | 2262 arguments, k)); |
| 2260 } | 2263 } |
| 2264 |
| 2265 @override |
| 2266 ir.Primitive buildReifyTypeVariable(TypeVariableType variable) { |
| 2267 return addPrimitive(new ir.ReifyTypeVar(variable.element)); |
| 2268 } |
| 2261 } | 2269 } |
| 2262 | 2270 |
| 2263 /// State shared between JsIrBuilders within the same function. | 2271 /// State shared between JsIrBuilders within the same function. |
| 2264 /// | 2272 /// |
| 2265 /// Note that this is not shared between builders of nested functions. | 2273 /// Note that this is not shared between builders of nested functions. |
| 2266 class JsIrBuilderSharedState { | 2274 class JsIrBuilderSharedState { |
| 2267 /// Maps boxed locals to their location. These locals are not part of | 2275 /// Maps boxed locals to their location. These locals are not part of |
| 2268 /// the environment. | 2276 /// the environment. |
| 2269 final Map<Local, ClosureLocation> boxedVariables = {}; | 2277 final Map<Local, ClosureLocation> boxedVariables = {}; |
| 2270 | 2278 |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2478 for (VariableElement loopVar in scope.boxedLoopVariables) { | 2486 for (VariableElement loopVar in scope.boxedLoopVariables) { |
| 2479 ClosureLocation location = scope.capturedVariables[loopVar]; | 2487 ClosureLocation location = scope.capturedVariables[loopVar]; |
| 2480 ir.Primitive value = addPrimitive(new ir.GetField(box, location.field)); | 2488 ir.Primitive value = addPrimitive(new ir.GetField(box, location.field)); |
| 2481 add(new ir.SetField(newBox, location.field, value)); | 2489 add(new ir.SetField(newBox, location.field, value)); |
| 2482 } | 2490 } |
| 2483 environment.update(scope.box, newBox); | 2491 environment.update(scope.box, newBox); |
| 2484 } | 2492 } |
| 2485 | 2493 |
| 2486 ir.Primitive buildThis() { | 2494 ir.Primitive buildThis() { |
| 2487 if (jsState.receiver != null) return jsState.receiver; | 2495 if (jsState.receiver != null) return jsState.receiver; |
| 2496 assert(state.thisParameter != null); |
| 2488 return state.thisParameter; | 2497 return state.thisParameter; |
| 2489 } | 2498 } |
| 2490 | 2499 |
| 2491 @override | 2500 @override |
| 2492 ir.Primitive buildSuperFieldGet(FieldElement target) { | 2501 ir.Primitive buildSuperFieldGet(FieldElement target) { |
| 2493 return addPrimitive(new ir.GetField(buildThis(), target)); | 2502 return addPrimitive(new ir.GetField(buildThis(), target)); |
| 2494 } | 2503 } |
| 2495 | 2504 |
| 2496 @override | 2505 @override |
| 2497 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) { | 2506 ir.Primitive buildSuperFieldSet(FieldElement target, ir.Primitive value) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2547 arguments = new List<ir.Primitive>.from(arguments) | 2556 arguments = new List<ir.Primitive>.from(arguments) |
| 2548 ..addAll(typeArguments); | 2557 ..addAll(typeArguments); |
| 2549 } | 2558 } |
| 2550 return _continueWithExpression( | 2559 return _continueWithExpression( |
| 2551 (k) => new ir.InvokeConstructor(type, element, selector, | 2560 (k) => new ir.InvokeConstructor(type, element, selector, |
| 2552 arguments, k)); | 2561 arguments, k)); |
| 2553 } | 2562 } |
| 2554 | 2563 |
| 2555 ir.Primitive buildTypeExpression(DartType type) { | 2564 ir.Primitive buildTypeExpression(DartType type) { |
| 2556 if (type is TypeVariableType) { | 2565 if (type is TypeVariableType) { |
| 2557 return buildTypeVariableAccess(buildThis(), type); | 2566 return buildTypeVariableAccess(type); |
| 2558 } else if (type is InterfaceType) { | 2567 } else if (type is InterfaceType) { |
| 2559 List<ir.Primitive> arguments = <ir.Primitive>[]; | 2568 List<ir.Primitive> arguments = <ir.Primitive>[]; |
| 2560 type.forEachTypeVariable((TypeVariableType variable) { | 2569 type.forEachTypeVariable((TypeVariableType variable) { |
| 2561 ir.Primitive value = buildTypeVariableAccess(buildThis(), variable); | 2570 ir.Primitive value = buildTypeVariableAccess(variable); |
| 2562 arguments.add(value); | 2571 arguments.add(value); |
| 2563 }); | 2572 }); |
| 2564 return addPrimitive(new ir.TypeExpression(type, arguments)); | 2573 return addPrimitive(new ir.TypeExpression(type, arguments)); |
| 2565 } else { | 2574 } else { |
| 2566 // TypedefType can reach here, and possibly other things. | 2575 // TypedefType can reach here, and possibly other things. |
| 2567 throw 'unimplemented translation of type expression $type'; | 2576 throw 'unimplemented translation of type expression $type'; |
| 2568 } | 2577 } |
| 2569 } | 2578 } |
| 2570 | 2579 |
| 2571 ir.Primitive buildTypeVariableAccess(ir.Primitive target, | 2580 /// Obtains the internal type representation of the type held in [variable]. |
| 2572 TypeVariableType variable) { | 2581 /// |
| 2582 /// The value of [variable] is taken from the current receiver object, or |
| 2583 /// if we are currently building a constructor field initializer, from the |
| 2584 /// corresponding type argument (field initializers are evaluated before the |
| 2585 /// receiver object is created). |
| 2586 ir.Primitive buildTypeVariableAccess(TypeVariableType variable) { |
| 2573 ir.Parameter accessTypeArgumentParameter() { | 2587 ir.Parameter accessTypeArgumentParameter() { |
| 2574 for (int i = 0; i < environment.length; i++) { | 2588 for (int i = 0; i < environment.length; i++) { |
| 2575 Local local = environment.index2variable[i]; | 2589 Local local = environment.index2variable[i]; |
| 2576 if (local is TypeInformationParameter && | 2590 if (local is TypeInformationParameter && |
| 2577 local.variable == variable.element) { | 2591 local.variable == variable.element) { |
| 2578 return environment.index2value[i]; | 2592 return environment.index2value[i]; |
| 2579 } | 2593 } |
| 2580 } | 2594 } |
| 2581 throw 'unable to find constructor parameter for type variable $variable.'; | 2595 throw 'unable to find constructor parameter for type variable $variable.'; |
| 2582 } | 2596 } |
| 2583 | 2597 |
| 2584 if (jsState.inInitializers) { | 2598 if (jsState.inInitializers) { |
| 2585 return accessTypeArgumentParameter(); | 2599 return accessTypeArgumentParameter(); |
| 2586 } else { | 2600 } else { |
| 2601 ir.Primitive target = buildThis(); |
| 2587 return addPrimitive(new ir.ReadTypeVariable(variable, target)); | 2602 return addPrimitive(new ir.ReadTypeVariable(variable, target)); |
| 2588 } | 2603 } |
| 2589 } | 2604 } |
| 2605 |
| 2606 @override |
| 2607 ir.Primitive buildReifyTypeVariable(TypeVariableType variable) { |
| 2608 ir.Primitive typeArgument = buildTypeVariableAccess(variable); |
| 2609 return addPrimitive(new ir.ReifyRuntimeType(typeArgument)); |
| 2610 } |
| 2611 |
| 2612 ir.Primitive buildInvocationMirror(Selector selector, |
| 2613 List<ir.Primitive> arguments) { |
| 2614 return addPrimitive(new ir.CreateInvocationMirror(selector, arguments)); |
| 2615 } |
| 2590 } | 2616 } |
| 2591 | 2617 |
| 2592 | 2618 |
| 2593 /// Location of a variable relative to a given closure. | 2619 /// Location of a variable relative to a given closure. |
| 2594 class ClosureLocation { | 2620 class ClosureLocation { |
| 2595 /// If not `null`, this location is [box].[field]. | 2621 /// If not `null`, this location is [box].[field]. |
| 2596 /// The location of [box] can be obtained separately from an | 2622 /// The location of [box] can be obtained separately from an |
| 2597 /// enclosing [ClosureEnvironment] or [ClosureScope]. | 2623 /// enclosing [ClosureEnvironment] or [ClosureScope]. |
| 2598 /// If `null`, then the location is [field] on the enclosing function object. | 2624 /// If `null`, then the location is [field] on the enclosing function object. |
| 2599 final BoxLocal box; | 2625 final BoxLocal box; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2660 } | 2686 } |
| 2661 | 2687 |
| 2662 /// Synthetic parameter to a JavaScript factory method that takes the type | 2688 /// Synthetic parameter to a JavaScript factory method that takes the type |
| 2663 /// argument given for the type variable [variable]. | 2689 /// argument given for the type variable [variable]. |
| 2664 class TypeInformationParameter implements Local { | 2690 class TypeInformationParameter implements Local { |
| 2665 final TypeVariableElement variable; | 2691 final TypeVariableElement variable; |
| 2666 final ExecutableElement executableContext; | 2692 final ExecutableElement executableContext; |
| 2667 TypeInformationParameter(this.variable, this.executableContext); | 2693 TypeInformationParameter(this.variable, this.executableContext); |
| 2668 String get name => variable.name; | 2694 String get name => variable.name; |
| 2669 } | 2695 } |
| OLD | NEW |