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

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

Issue 1011403003: cps-ir: Set runtime type information for new objects that require it. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Add parameter for each type variable to the JS-factory. Created 5 years, 9 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 | Annotate | Revision Log
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; 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_types.dart'; 9 import '../dart_types.dart';
10 import '../dart2jslib.dart'; 10 import '../dart2jslib.dart';
11 import '../elements/elements.dart'; 11 import '../elements/elements.dart';
12 import '../io/source_information.dart'; 12 import '../io/source_information.dart';
13 import '../tree/tree.dart' as ast; 13 import '../tree/tree.dart' as ast;
14 import '../closure.dart' hide ClosureScope; 14 import '../closure.dart' hide ClosureScope;
15 import 'cps_ir_nodes.dart' as ir; 15 import 'cps_ir_nodes.dart' as ir;
16 import 'cps_ir_builder_task.dart' show DartCapturedVariables; 16 import 'cps_ir_builder_task.dart' show DartCapturedVariables,
17 GlobalProgramInformation;
17 18
18 /// A mapping from variable elements to their compile-time values. 19 /// A mapping from variable elements to their compile-time values.
19 /// 20 ///
20 /// Map elements denoted by parameters and local variables to the 21 /// Map elements denoted by parameters and local variables to the
21 /// [ir.Primitive] that is their value. Parameters and locals are 22 /// [ir.Primitive] that is their value. Parameters and locals are
22 /// assigned indexes which can be used to refer to them. 23 /// assigned indexes which can be used to refer to them.
23 class Environment { 24 class Environment {
24 /// A map from locals to their environment index. 25 /// A map from locals to their environment index.
25 final Map<Local, int> variable2index; 26 final Map<Local, int> variable2index;
26 27
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 /// Called before building the body of a for-loop. 289 /// Called before building the body of a for-loop.
289 void _enterForLoopBody(ClosureScope scope, 290 void _enterForLoopBody(ClosureScope scope,
290 List<LocalElement> loopVariables); 291 List<LocalElement> loopVariables);
291 292
292 /// Called before building the update of a for-loop. 293 /// Called before building the update of a for-loop.
293 void _enterForLoopUpdate(ClosureScope scope, 294 void _enterForLoopUpdate(ClosureScope scope,
294 List<LocalElement> loopVariables); 295 List<LocalElement> loopVariables);
295 296
296 /// Add the given function parameter to the IR, and bind it in the environment 297 /// Add the given function parameter to the IR, and bind it in the environment
297 /// or put it in its box, if necessary. 298 /// or put it in its box, if necessary.
298 void _createFunctionParameter(ParameterElement parameterElement); 299 void _createFunctionParameter(Local parameterElement);
299 300
300 /// Creates an access to the receiver from the current (or enclosing) method. 301 /// Creates an access to the receiver from the current (or enclosing) method.
301 /// 302 ///
302 /// If inside a closure class, [buildThis] will redirect access through 303 /// If inside a closure class, [buildThis] will redirect access through
303 /// closure fields in order to access the receiver from the enclosing method. 304 /// closure fields in order to access the receiver from the enclosing method.
304 ir.Primitive buildThis(); 305 ir.Primitive buildThis();
305 306
306 // TODO(johnniwinther): Make these field final and remove the default values 307 // TODO(johnniwinther): Make these field final and remove the default values
307 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin. 308 // when [IrBuilder] is a property of [IrBuilderVisitor] instead of a mixin.
308 309
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 ..environment = new Environment.empty(); 393 ..environment = new Environment.empty();
393 } 394 }
394 395
395 bool get isOpen => _root == null || _current != null; 396 bool get isOpen => _root == null || _current != null;
396 397
397 398
398 void buildFieldInitializerHeader({ClosureScope closureScope}) { 399 void buildFieldInitializerHeader({ClosureScope closureScope}) {
399 _enterScope(closureScope); 400 _enterScope(closureScope);
400 } 401 }
401 402
402 List<ir.Primitive> buildFunctionHeader(Iterable<ParameterElement> parameters, 403 List<ir.Primitive> buildFunctionHeader(Iterable<Local> parameters,
403 {ClosureScope closureScope, 404 {ClosureScope closureScope,
404 ClosureEnvironment env}) { 405 ClosureEnvironment env}) {
405 _enterClosureEnvironment(env); 406 _enterClosureEnvironment(env);
406 _enterScope(closureScope); 407 _enterScope(closureScope);
407 parameters.forEach(_createFunctionParameter); 408 parameters.forEach(_createFunctionParameter);
408 return _parameters; 409 return _parameters;
409 } 410 }
410 411
411 /// Creates a parameter for [local] and adds it to the current environment. 412 /// Creates a parameter for [local] and adds it to the current environment.
412 ir.Parameter createLocalParameter(Local local) { 413 ir.Parameter createLocalParameter(Local local) {
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
780 _buildInvokeStatic( 781 _buildInvokeStatic(
781 element, selector, <ir.Primitive>[value], sourceInformation); 782 element, selector, <ir.Primitive>[value], sourceInformation);
782 return value; 783 return value;
783 } 784 }
784 785
785 /// Create a constructor invocation of [element] on [type] where the 786 /// Create a constructor invocation of [element] on [type] where the
786 /// constructor name and argument structure are defined by [selector] and the 787 /// constructor name and argument structure are defined by [selector] and the
787 /// argument values are defined by [arguments]. 788 /// argument values are defined by [arguments].
788 ir.Primitive buildConstructorInvocation(FunctionElement element, 789 ir.Primitive buildConstructorInvocation(FunctionElement element,
789 Selector selector, 790 Selector selector,
790 DartType type, 791 InterfaceType type,
791 List<ir.Primitive> arguments) { 792 List<ir.Primitive> arguments);
792 assert(isOpen);
793 return _continueWithExpression(
794 (k) => new ir.InvokeConstructor(type, element, selector, k, arguments));
795 }
796 793
797 /// Create a string concatenation of the [arguments]. 794 /// Create a string concatenation of the [arguments].
798 ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments) { 795 ir.Primitive buildStringConcatenation(List<ir.Primitive> arguments) {
799 assert(isOpen); 796 assert(isOpen);
800 return _continueWithExpression( 797 return _continueWithExpression(
801 (k) => new ir.ConcatenateStrings(k, arguments)); 798 (k) => new ir.ConcatenateStrings(k, arguments));
802 } 799 }
803 800
804 /// Create an invocation of the `call` method of [functionExpression], where 801 /// Create an invocation of the `call` method of [functionExpression], where
805 /// the named arguments are given by [selector]. 802 /// the named arguments are given by [selector].
(...skipping 1213 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 if (isInMutableVariable(loopVariable)) { 2016 if (isInMutableVariable(loopVariable)) {
2020 ir.MutableVariable mutableVariable = getMutableVariable(loopVariable); 2017 ir.MutableVariable mutableVariable = getMutableVariable(loopVariable);
2021 ir.Primitive get = new ir.GetMutableVariable(mutableVariable); 2018 ir.Primitive get = new ir.GetMutableVariable(mutableVariable);
2022 add(new ir.LetPrim(get)); 2019 add(new ir.LetPrim(get));
2023 environment.update(loopVariable, get); 2020 environment.update(loopVariable, get);
2024 dartState.registerizedMutableVariables.add(loopVariable); 2021 dartState.registerizedMutableVariables.add(loopVariable);
2025 } 2022 }
2026 } 2023 }
2027 } 2024 }
2028 2025
2029 void _createFunctionParameter(ParameterElement parameterElement) { 2026 void _createFunctionParameter(Local parameterElement) {
2030 ir.Parameter parameter = new ir.Parameter(parameterElement); 2027 ir.Parameter parameter = new ir.Parameter(parameterElement);
2031 _parameters.add(parameter); 2028 _parameters.add(parameter);
2032 if (isInMutableVariable(parameterElement)) { 2029 if (isInMutableVariable(parameterElement)) {
2033 state.functionParameters.add(getMutableVariable(parameterElement)); 2030 state.functionParameters.add(getMutableVariable(parameterElement));
2034 } else { 2031 } else {
2035 state.functionParameters.add(parameter); 2032 state.functionParameters.add(parameter);
2036 environment.extend(parameterElement, parameter); 2033 environment.extend(parameterElement, parameter);
2037 } 2034 }
2038 } 2035 }
2039 2036
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
2106 add(new ir.LetPrim(thisPrim)); 2103 add(new ir.LetPrim(thisPrim));
2107 return thisPrim; 2104 return thisPrim;
2108 } 2105 }
2109 2106
2110 ir.Primitive buildSuperInvocation(Element target, 2107 ir.Primitive buildSuperInvocation(Element target,
2111 Selector selector, 2108 Selector selector,
2112 List<ir.Primitive> arguments) { 2109 List<ir.Primitive> arguments) {
2113 return _buildInvokeSuper(target, selector, arguments); 2110 return _buildInvokeSuper(target, selector, arguments);
2114 } 2111 }
2115 2112
2113 @override
2114 ir.Primitive buildConstructorInvocation(FunctionElement element,
2115 Selector selector,
2116 InterfaceType type,
2117 List<ir.Primitive> arguments) {
2118 assert(isOpen);
2119 return _continueWithExpression(
2120 (k) => new ir.InvokeConstructor(type, element, selector, k,
2121 arguments));
2122 }
2116 } 2123 }
2117 2124
2118 /// State shared between JsIrBuilders within the same function. 2125 /// State shared between JsIrBuilders within the same function.
2119 /// 2126 ///
2120 /// Note that this is not shared between builders of nested functions. 2127 /// Note that this is not shared between builders of nested functions.
2121 class JsIrBuilderSharedState { 2128 class JsIrBuilderSharedState {
2122 /// Maps boxed locals to their location. These locals are not part of 2129 /// Maps boxed locals to their location. These locals are not part of
2123 /// the environment. 2130 /// the environment.
2124 final Map<Local, ClosureLocation> boxedVariables = {}; 2131 final Map<Local, ClosureLocation> boxedVariables = {};
2125 2132
2126 /// If non-null, this refers to the receiver (`this`) in the enclosing method. 2133 /// If non-null, this refers to the receiver (`this`) in the enclosing method.
2127 ir.Primitive receiver; 2134 ir.Primitive receiver;
2135
2136 /// `true` when we are currently building expressions inside the initializer
2137 /// list of a constructor.
2138 bool inInitializers = false;
2128 } 2139 }
2129 2140
2130 /// JS-specific subclass of [IrBuilder]. 2141 /// JS-specific subclass of [IrBuilder].
2131 /// 2142 ///
2132 /// Inner functions are represented by a [ClosureClassElement], and captured 2143 /// Inner functions are represented by a [ClosureClassElement], and captured
2133 /// variables are boxed as necessary using [CreateBox], [GetField], [SetField]. 2144 /// variables are boxed as necessary using [CreateBox], [GetField], [SetField].
2134 class JsIrBuilder extends IrBuilder { 2145 class JsIrBuilder extends IrBuilder {
2135 final JsIrBuilderSharedState jsState; 2146 final JsIrBuilderSharedState jsState;
2147 final GlobalProgramInformation program;
2136 2148
2137 IrBuilder _makeInstance() => new JsIrBuilder._blank(jsState); 2149 IrBuilder _makeInstance() => new JsIrBuilder._blank(program, jsState);
2138 JsIrBuilder._blank(this.jsState); 2150 JsIrBuilder._blank(this.program, this.jsState);
2139 2151
2140 JsIrBuilder(ConstantSystem constantSystem, ExecutableElement currentElement) 2152 JsIrBuilder(this.program, ConstantSystem constantSystem,
2153 ExecutableElement currentElement)
2141 : jsState = new JsIrBuilderSharedState() { 2154 : jsState = new JsIrBuilderSharedState() {
2142 _init(constantSystem, currentElement); 2155 _init(constantSystem, currentElement);
2143 } 2156 }
2144 2157
2145 Map<ast.TryStatement, TryStatementInfo> get tryStatements => null; 2158 Map<ast.TryStatement, TryStatementInfo> get tryStatements => null;
2146 Set<Local> get mutableCapturedVariables => null; 2159 Set<Local> get mutableCapturedVariables => null;
2147 bool isInMutableVariable(Local local) => false; 2160 bool isInMutableVariable(Local local) => false;
2148 void makeMutableVariable(Local local) {} 2161 void makeMutableVariable(Local local) {}
2149 void removeMutableVariable(Local local) {} 2162 void removeMutableVariable(Local local) {}
2150 2163
2164 void enterInitializers() {
2165 assert(jsState.inInitializers == false);
2166 jsState.inInitializers = true;
2167 }
2168
2169 void leaveInitializers() {
2170 assert(jsState.inInitializers == true);
2171 jsState.inInitializers = false;
2172 }
2173
2151 void _enterClosureEnvironment(ClosureEnvironment env) { 2174 void _enterClosureEnvironment(ClosureEnvironment env) {
2152 if (env == null) return; 2175 if (env == null) return;
2153 2176
2154 // Obtain a reference to the function object (this). 2177 // Obtain a reference to the function object (this).
2155 ir.Primitive thisPrim = new ir.This(); 2178 ir.Primitive thisPrim = new ir.This();
2156 add(new ir.LetPrim(thisPrim)); 2179 add(new ir.LetPrim(thisPrim));
2157 2180
2158 // Obtain access to the free variables. 2181 // Obtain access to the free variables.
2159 env.freeVariables.forEach((Local local, ClosureLocation location) { 2182 env.freeVariables.forEach((Local local, ClosureLocation location) {
2160 if (location.isBox) { 2183 if (location.isBox) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2195 environment.extend(scope.box, boxPrim); 2218 environment.extend(scope.box, boxPrim);
2196 boxPrim.useElementAsHint(scope.box); 2219 boxPrim.useElementAsHint(scope.box);
2197 scope.capturedVariables.forEach((Local local, ClosureLocation location) { 2220 scope.capturedVariables.forEach((Local local, ClosureLocation location) {
2198 assert(!jsState.boxedVariables.containsKey(local)); 2221 assert(!jsState.boxedVariables.containsKey(local));
2199 if (location.isBox) { 2222 if (location.isBox) {
2200 jsState.boxedVariables[local] = location; 2223 jsState.boxedVariables[local] = location;
2201 } 2224 }
2202 }); 2225 });
2203 } 2226 }
2204 2227
2205 void _createFunctionParameter(ParameterElement parameterElement) { 2228 void _createFunctionParameter(Local parameterElement) {
2206 ir.Parameter parameter = new ir.Parameter(parameterElement); 2229 ir.Parameter parameter = new ir.Parameter(parameterElement);
2207 _parameters.add(parameter); 2230 _parameters.add(parameter);
2208 state.functionParameters.add(parameter); 2231 state.functionParameters.add(parameter);
2209 ClosureLocation location = jsState.boxedVariables[parameterElement]; 2232 ClosureLocation location = jsState.boxedVariables[parameterElement];
2210 if (location != null) { 2233 if (location != null) {
2211 add(new ir.SetField(environment.lookup(location.box), 2234 add(new ir.SetField(environment.lookup(location.box),
2212 location.field, 2235 location.field,
2213 parameter)); 2236 parameter));
2214 } else { 2237 } else {
2215 environment.extend(parameterElement, parameter); 2238 environment.extend(parameterElement, parameter);
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
2371 void buildConstructorBodyHeader(Iterable<Local> parameters, 2394 void buildConstructorBodyHeader(Iterable<Local> parameters,
2372 ClosureScope closureScope) { 2395 ClosureScope closureScope) {
2373 for (Local param in parameters) { 2396 for (Local param in parameters) {
2374 ir.Parameter parameter = createLocalParameter(param); 2397 ir.Parameter parameter = createLocalParameter(param);
2375 state.functionParameters.add(parameter); 2398 state.functionParameters.add(parameter);
2376 } 2399 }
2377 if (closureScope != null) { 2400 if (closureScope != null) {
2378 jsState.boxedVariables.addAll(closureScope.capturedVariables); 2401 jsState.boxedVariables.addAll(closureScope.capturedVariables);
2379 } 2402 }
2380 } 2403 }
2404
2405 @override
2406 ir.Primitive buildConstructorInvocation(FunctionElement element,
2407 Selector selector,
2408 InterfaceType type,
2409 List<ir.Primitive> arguments) {
2410 assert(isOpen);
2411 // TODO(karlklose): resolve effective target and type here or inline later?
2412 ClassElement cls = element.enclosingClass;
2413 Iterable<ir.Primitive> typeArguments = const <ir.Primitive>[];
2414 if (program.requiresRuntimeTypesFor(cls)) {
2415 ir.Primitive argumentArray;
2416 typeArguments = type.typeArguments.map((DartType argument) {
2417 return type.treatAsRaw
2418 ? buildNullLiteral()
2419 : buildTypeExpression(argument);
2420 });
2421 arguments = new List<ir.Primitive>.from(arguments)
2422 ..addAll(typeArguments);
2423 }
2424 return _continueWithExpression(
2425 (k) => new ir.InvokeConstructor(type, element, selector, k,
2426 arguments));
2427 }
2428
2429 ir.Primitive buildTypeExpression(DartType type) {
2430 if (type is TypeVariableType) {
2431 return buildTypeVariableAccess(buildThis(), type);
2432 } else {
2433 assert(type is InterfaceType);
2434 // TODO(karlklose): optimization: share the type expression for variables.
2435 List<ir.Primitive> arguments = <ir.Primitive>[];
2436 type.forEachTypeVariable((TypeVariableType variable) {
2437 ir.Primitive value = buildTypeExpression(variable);
2438 arguments.add(value);
2439 });
2440 // TODO(karlklose): use addPrimitive.
2441 ir.Primitive expression = new ir.TypeExpression(type, arguments);
2442 add(new ir.LetPrim(expression));
2443 return expression;
2444 }
2445 }
2446
2447 ir.Primitive buildTypeVariableAccess(ir.Primitive target,
2448 TypeVariableType variable) {
2449 ir.Parameter accessTypeArgumentParameter() {
2450 for (int i = 0; i < environment.length; i++) {
2451 Local local = environment.index2variable[i];
2452 if (local is TypeInformationParameter &&
2453 local.variable == variable.element) {
2454 return environment.index2value[i];
2455 }
2456 }
2457 throw 'unable to find constructor parameter for type variable $variable.';
2458 }
2459
2460 // TODO(karlklose): use addPrimitive.
2461 if (jsState.inInitializers) {
2462 return accessTypeArgumentParameter();
2463 } else {
2464 ir.Primitive result = new ir.ReadTypeVariable(variable, target);
2465 add(new ir.LetPrim(result));
2466 return result;
2467 }
2468 }
2381 } 2469 }
2382 2470
2383 2471
2384 /// Location of a variable relative to a given closure. 2472 /// Location of a variable relative to a given closure.
2385 class ClosureLocation { 2473 class ClosureLocation {
2386 /// If not `null`, this location is [box].[field]. 2474 /// If not `null`, this location is [box].[field].
2387 /// The location of [box] can be obtained separately from an 2475 /// The location of [box] can be obtained separately from an
2388 /// enclosing [ClosureEnvironment] or [ClosureScope]. 2476 /// enclosing [ClosureEnvironment] or [ClosureScope].
2389 /// If `null`, then the location is [field] on the enclosing function object. 2477 /// If `null`, then the location is [field] on the enclosing function object.
2390 final BoxLocal box; 2478 final BoxLocal box;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2442 // TODO(johnniwinther): Support passing of [DartType] for the exception. 2530 // TODO(johnniwinther): Support passing of [DartType] for the exception.
2443 class CatchClauseInfo { 2531 class CatchClauseInfo {
2444 final LocalVariableElement exceptionVariable; 2532 final LocalVariableElement exceptionVariable;
2445 final LocalVariableElement stackTraceVariable; 2533 final LocalVariableElement stackTraceVariable;
2446 final SubbuildFunction buildCatchBlock; 2534 final SubbuildFunction buildCatchBlock;
2447 2535
2448 CatchClauseInfo({this.exceptionVariable, 2536 CatchClauseInfo({this.exceptionVariable,
2449 this.stackTraceVariable, 2537 this.stackTraceVariable,
2450 this.buildCatchBlock}); 2538 this.buildCatchBlock});
2451 } 2539 }
2540
2541 /// The synthetic parameter to a factory that takes the runtime type information
2542 /// to be set on the new instance.
2543 class TypeInformationParameter implements Local {
2544 final TypeVariableElement variable;
2545 final ExecutableElement executableContext;
2546 TypeInformationParameter(this.variable, this.executableContext);
2547 String get name => variable.name;
2548 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart » ('j') | pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698