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 2017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |