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

Side by Side Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.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: Update comment. 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_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 2017 matching lines...) Expand 10 before | Expand all | Expand 10 after
2028 @override 2028 @override
2029 ir.Primitive buildReifyTypeVariable(ir.Primitive target, 2029 ir.Primitive buildReifyTypeVariable(ir.Primitive target,
2030 TypeVariableType variable) { 2030 TypeVariableType variable) {
2031 assert(target == irBuilder.state.enclosingMethodThisParameter); 2031 assert(target == irBuilder.state.enclosingMethodThisParameter);
2032 ir.Primitive prim = new ir.ReifyTypeVar(variable.element); 2032 ir.Primitive prim = new ir.ReifyTypeVar(variable.element);
2033 irBuilder.add(new ir.LetPrim(prim)); 2033 irBuilder.add(new ir.LetPrim(prim));
2034 return prim; 2034 return prim;
2035 } 2035 }
2036 } 2036 }
2037 2037
2038 /// The [IrBuilder]s view on the information about the program that has been
2039 /// computed in resolution and and type interence.
2040 class GlobalProgramInformation {
2041 final Compiler _compiler;
2042 JavaScriptBackend get _backend => _compiler.backend;
2043
2044 GlobalProgramInformation(this._compiler);
2045
2046 /// Returns [true], if the analysis could not determine that the type
2047 /// arguments for the class [cls] are never used in the program.
2048 bool requiresRuntimeTypesFor(ClassElement cls) {
2049 return cls.typeVariables.isNotEmpty && _backend.classNeedsRti(cls);
2050 }
2051 }
2052
2038 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. 2053 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder].
2039 class JsIrBuilderVisitor extends IrBuilderVisitor { 2054 class JsIrBuilderVisitor extends IrBuilderVisitor {
2040 /// Promote the type of [irBuilder] to [JsIrBuilder]. 2055 /// Promote the type of [irBuilder] to [JsIrBuilder].
2041 JsIrBuilder get irBuilder => super.irBuilder; 2056 JsIrBuilder get irBuilder => super.irBuilder;
2042 2057
2043 /// Result of closure conversion for the current body of code. 2058 /// Result of closure conversion for the current body of code.
2044 /// 2059 ///
2045 /// Will be initialized upon entering the body of a function. 2060 /// Will be initialized upon entering the body of a function.
2046 /// It is computed by the [ClosureTranslator]. 2061 /// It is computed by the [ClosureTranslator].
2047 ClosureClassMap closureMap; 2062 ClosureClassMap closureMap;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
2173 /// Such constants need to be compiled with a different [sourceFile] and 2188 /// Such constants need to be compiled with a different [sourceFile] and
2174 /// [elements] mapping. 2189 /// [elements] mapping.
2175 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) { 2190 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) {
2176 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( 2191 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor(
2177 context.resolvedAst.elements, 2192 context.resolvedAst.elements,
2178 compiler, 2193 compiler,
2179 sourceInformationBuilder.forContext(context)); 2194 sourceInformationBuilder.forContext(context));
2180 return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp)); 2195 return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp));
2181 } 2196 }
2182 2197
2198 JsIrBuilder getBuilderFor(Element element) {
2199 return new JsIrBuilder(
2200 new GlobalProgramInformation(compiler),
2201 compiler.backend.constantSystem,
2202 element);
2203 }
2204
2183 /// Builds the IR for a given constructor. 2205 /// Builds the IR for a given constructor.
2184 /// 2206 ///
2185 /// 1. Evaluates all own or inherited field initializers. 2207 /// 1. Evaluates all own or inherited field initializers.
2186 /// 2. Creates the object and assigns its fields. 2208 /// 2. Creates the object and assigns its fields.
2187 /// 3. Calls constructor body and super constructor bodies. 2209 /// 3. Calls constructor body and super constructor bodies.
2188 /// 4. Returns the created object. 2210 /// 4. Returns the created object.
2189 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { 2211 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) {
2190 constructor = constructor.implementation; 2212 constructor = constructor.implementation;
2191 ClassElement classElement = constructor.enclosingClass.implementation; 2213 ClassElement classElement = constructor.enclosingClass.implementation;
2192 2214
2193 JsIrBuilder builder = 2215 JsIrBuilder builder = getBuilderFor(constructor);
2194 new JsIrBuilder(compiler.backend.constantSystem, constructor); 2216
2217 final bool requiresTypeInformation =
2218 builder.program.requiresRuntimeTypesFor(classElement);
2195 2219
2196 return withBuilder(builder, () { 2220 return withBuilder(builder, () {
2197 // Setup parameters and create a box if anything is captured. 2221 // Setup parameters and create a box if anything is captured.
2198 List<ParameterElement> parameters = []; 2222 List<Local> parameters = <Local>[];
2199 constructor.functionSignature.orderedForEachParameter(parameters.add); 2223 constructor.functionSignature.orderedForEachParameter(
2200 builder.buildFunctionHeader(parameters, 2224 // Note: the closure is explicit to allow typechecking [FormalElement]
2225 // against [Local].
asgerf 2015/03/24 12:37:21 That's unfortunate, but I think the comment actual
karlklose 2015/03/26 09:50:07 Done. But we need to address the mixup of [Element
asgerf 2015/03/26 09:58:41 Completely agree.
2226 (ParameterElement p) => parameters.add(p));
2227
2228 int firstTypeArgumentParameterIndex;
2229
2230 // If instances of the class may need runtime type information, we add a
2231 // synthetic parameter for each type parameter.
2232 if (requiresTypeInformation) {
2233 firstTypeArgumentParameterIndex = parameters.length;
2234 classElement.typeVariables.forEach((TypeVariableType variable) {
2235 parameters.add(
2236 new TypeInformationParameter(variable.element, constructor));
2237 });
2238 }
2239
2240 // Create IR parameters and setup the environment.
2241 List<ir.Parameter> irParameters = builder.buildFunctionHeader(parameters,
2201 closureScope: getClosureScopeForFunction(constructor)); 2242 closureScope: getClosureScopeForFunction(constructor));
2202 2243
2244 // Create a list of the values of all type argument parameters, if any.
2245 List<ir.Primitive> typeInformation;
2246 if (requiresTypeInformation) {
2247 List<ir.Primitive> typeArgumentParameters = <ir.Primitive>[];
2248 for (int index = firstTypeArgumentParameterIndex;
2249 index < irParameters.length;
2250 ++index) {
2251 typeArgumentParameters.add(irParameters[index]);
2252 }
2253 typeInformation = typeArgumentParameters;
asgerf 2015/03/24 12:37:21 How about: typeInformation = irParameters.sublist
karlklose 2015/03/26 09:50:07 Done.
2254 }
2255
2203 // -- Step 1: evaluate field initializers --- 2256 // -- Step 1: evaluate field initializers ---
2204 // Evaluate field initializers in constructor and super constructors. 2257 // Evaluate field initializers in constructor and super constructors.
2258 irBuilder.enterInitializers();
2205 List<ConstructorElement> constructorList = <ConstructorElement>[]; 2259 List<ConstructorElement> constructorList = <ConstructorElement>[];
2206 evaluateConstructorFieldInitializers(constructor, constructorList); 2260 evaluateConstructorFieldInitializers(constructor, constructorList);
2261 irBuilder.leaveInitializers();
2207 2262
2208 // All parameters in all constructors are now bound in the environment. 2263 // All parameters in all constructors are now bound in the environment.
2209 // BoxLocals for captured parameters are also in the environment. 2264 // BoxLocals for captured parameters are also in the environment.
2210 // The initial value of all fields are now bound in [fieldValues]. 2265 // The initial value of all fields are now bound in [fieldValues].
2211 2266
2212 // --- Step 2: create the object --- 2267 // --- Step 2: create the object ---
2213 // Get the initial field values in the canonical order. 2268 // Get the initial field values in the canonical order.
2214 List<ir.Primitive> instanceArguments = <ir.Primitive>[]; 2269 List<ir.Primitive> instanceArguments = <ir.Primitive>[];
2215 classElement.forEachInstanceField((ClassElement c, FieldElement field) { 2270 classElement.forEachInstanceField((ClassElement c, FieldElement field) {
2216 ir.Primitive value = fieldValues[field]; 2271 ir.Primitive value = fieldValues[field];
2217 if (value != null) { 2272 if (value != null) {
2218 instanceArguments.add(fieldValues[field]); 2273 instanceArguments.add(fieldValues[field]);
2219 } else { 2274 } else {
2220 assert(Elements.isNativeOrExtendsNative(c)); 2275 assert(Elements.isNativeOrExtendsNative(c));
2221 // Native fields are initialized elsewhere. 2276 // Native fields are initialized elsewhere.
2222 } 2277 }
2223 }, includeSuperAndInjectedMembers: true); 2278 }, includeSuperAndInjectedMembers: true);
2224 ir.Primitive instance = 2279 ir.Primitive instance = new ir.CreateInstance(
2225 new ir.CreateInstance(classElement, instanceArguments); 2280 classElement,
2281 instanceArguments,
2282 typeInformation);
2226 irBuilder.add(new ir.LetPrim(instance)); 2283 irBuilder.add(new ir.LetPrim(instance));
2227 2284
2228 // --- Step 3: call constructor bodies --- 2285 // --- Step 3: call constructor bodies ---
2229 for (ConstructorElement target in constructorList) { 2286 for (ConstructorElement target in constructorList) {
2230 ConstructorBodyElement bodyElement = getConstructorBody(target); 2287 ConstructorBodyElement bodyElement = getConstructorBody(target);
2231 if (bodyElement == null) continue; // Skip if constructor has no body. 2288 if (bodyElement == null) continue; // Skip if constructor has no body.
2232 List<ir.Primitive> bodyArguments = <ir.Primitive>[]; 2289 List<ir.Primitive> bodyArguments = <ir.Primitive>[];
2233 for (Local param in getConstructorBodyParameters(bodyElement)) { 2290 for (Local param in getConstructorBodyParameters(bodyElement)) {
2234 bodyArguments.add(irBuilder.environment.lookup(param)); 2291 bodyArguments.add(irBuilder.environment.lookup(param));
2235 } 2292 }
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
2449 /// This function is invoked from one or more "factory" constructors built by 2506 /// This function is invoked from one or more "factory" constructors built by
2450 /// [buildConstructor]. 2507 /// [buildConstructor].
2451 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { 2508 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) {
2452 ConstructorElement constructor = body.constructor; 2509 ConstructorElement constructor = body.constructor;
2453 ast.FunctionExpression node = constructor.node; 2510 ast.FunctionExpression node = constructor.node;
2454 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( 2511 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping(
2455 constructor, 2512 constructor,
2456 node, 2513 node,
2457 elements); 2514 elements);
2458 2515
2459 JsIrBuilder builder = 2516 JsIrBuilder builder = getBuilderFor(body);
2460 new JsIrBuilder(compiler.backend.constantSystem, body);
2461 2517
2462 return withBuilder(builder, () { 2518 return withBuilder(builder, () {
2463 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), 2519 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body),
2464 getClosureScopeForNode(node)); 2520 getClosureScopeForNode(node));
2465 visit(node.body); 2521 visit(node.body);
2466 return irBuilder.makeFunctionDefinition([]); 2522 return irBuilder.makeFunctionDefinition([]);
2467 }); 2523 });
2468 } 2524 }
2469 2525
2470 ir.FunctionDefinition buildFunction(FunctionElement element) { 2526 ir.FunctionDefinition buildFunction(FunctionElement element) {
2471 assert(invariant(element, element.isImplementation)); 2527 assert(invariant(element, element.isImplementation));
2472 ast.FunctionExpression node = element.node; 2528 ast.FunctionExpression node = element.node;
2473 2529
2474 assert(!element.isSynthesized); 2530 assert(!element.isSynthesized);
2475 assert(node != null); 2531 assert(node != null);
2476 assert(elements[node] != null); 2532 assert(elements[node] != null);
2477 2533
2478 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( 2534 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping(
2479 element, 2535 element,
2480 node, 2536 node,
2481 elements); 2537 elements);
2482 IrBuilder builder = 2538 IrBuilder builder = getBuilderFor(element);
2483 new JsIrBuilder(compiler.backend.constantSystem, element);
2484 return withBuilder(builder, () => _makeFunctionBody(element, node)); 2539 return withBuilder(builder, () => _makeFunctionBody(element, node));
2485 } 2540 }
2486 2541
2487 /// Creates a primitive for the default value of [parameter]. 2542 /// Creates a primitive for the default value of [parameter].
2488 ir.Primitive translateDefaultValue(ParameterElement parameter) { 2543 ir.Primitive translateDefaultValue(ParameterElement parameter) {
2489 if (parameter.initializer == null) { 2544 if (parameter.initializer == null) {
2490 return irBuilder.buildNullLiteral(); 2545 return irBuilder.buildNullLiteral();
2491 } else { 2546 } else {
2492 return inlineConstant(parameter.executableContext, parameter.initializer); 2547 return inlineConstant(parameter.executableContext, parameter.initializer);
2493 } 2548 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2555 int nameIndex = selector.namedArguments.indexOf(argName); 2610 int nameIndex = selector.namedArguments.indexOf(argName);
2556 int translatedIndex = selector.positionalArgumentCount + nameIndex; 2611 int translatedIndex = selector.positionalArgumentCount + nameIndex;
2557 result.add(arguments[translatedIndex]); 2612 result.add(arguments[translatedIndex]);
2558 } 2613 }
2559 return result; 2614 return result;
2560 } 2615 }
2561 2616
2562 @override 2617 @override
2563 ir.Primitive buildReifyTypeVariable(ir.Primitive target, 2618 ir.Primitive buildReifyTypeVariable(ir.Primitive target,
2564 TypeVariableType variable) { 2619 TypeVariableType variable) {
2565 ir.Primitive typeArgument = new ir.ReadTypeVariable(variable, target); 2620 ir.Primitive typeArgument =
2566 irBuilder.add(new ir.LetPrim(typeArgument)); 2621 irBuilder.buildTypeVariableAccess(target, variable);
2622
2567 ir.Primitive type = new ir.ReifyRuntimeType(typeArgument); 2623 ir.Primitive type = new ir.ReifyRuntimeType(typeArgument);
2568 irBuilder.add(new ir.LetPrim(type)); 2624 irBuilder.add(new ir.LetPrim(type));
2569 return type; 2625 return type;
2570 } 2626 }
2571 } 2627 }
2572 2628
2573 /// Interface for generating [SourceInformation] for the CPS. 2629 /// Interface for generating [SourceInformation] for the CPS.
2574 class SourceInformationBuilder { 2630 class SourceInformationBuilder {
2575 const SourceInformationBuilder(); 2631 const SourceInformationBuilder();
2576 2632
(...skipping 26 matching lines...) Expand all
2603 SourceInformation buildCall(ast.Node node) { 2659 SourceInformation buildCall(ast.Node node) {
2604 return new PositionSourceInformation( 2660 return new PositionSourceInformation(
2605 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); 2661 new TokenSourceLocation(sourceFile, node.getBeginToken(), name));
2606 } 2662 }
2607 2663
2608 @override 2664 @override
2609 SourceInformationBuilder forContext(AstElement element) { 2665 SourceInformationBuilder forContext(AstElement element) {
2610 return new PositionSourceInformationBuilder(element); 2666 return new PositionSourceInformationBuilder(element);
2611 } 2667 }
2612 } 2668 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698