| 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 (ParameterElement p) => parameters.add(p)); |
| 2225 |
| 2226 int firstTypeArgumentParameterIndex; |
| 2227 |
| 2228 // If instances of the class may need runtime type information, we add a |
| 2229 // synthetic parameter for each type parameter. |
| 2230 if (requiresTypeInformation) { |
| 2231 firstTypeArgumentParameterIndex = parameters.length; |
| 2232 classElement.typeVariables.forEach((TypeVariableType variable) { |
| 2233 parameters.add( |
| 2234 new TypeInformationParameter(variable.element, constructor)); |
| 2235 }); |
| 2236 } |
| 2237 |
| 2238 // Create IR parameters and setup the environment. |
| 2239 List<ir.Parameter> irParameters = builder.buildFunctionHeader(parameters, |
| 2201 closureScope: getClosureScopeForFunction(constructor)); | 2240 closureScope: getClosureScopeForFunction(constructor)); |
| 2202 | 2241 |
| 2242 // Create a list of the values of all type argument parameters, if any. |
| 2243 List<ir.Primitive> typeInformation; |
| 2244 if (requiresTypeInformation) { |
| 2245 typeInformation = irParameters.sublist(firstTypeArgumentParameterIndex); |
| 2246 } else { |
| 2247 typeInformation = const <ir.Primitive>[]; |
| 2248 } |
| 2249 |
| 2203 // -- Step 1: evaluate field initializers --- | 2250 // -- Step 1: evaluate field initializers --- |
| 2204 // Evaluate field initializers in constructor and super constructors. | 2251 // Evaluate field initializers in constructor and super constructors. |
| 2252 irBuilder.enterInitializers(); |
| 2205 List<ConstructorElement> constructorList = <ConstructorElement>[]; | 2253 List<ConstructorElement> constructorList = <ConstructorElement>[]; |
| 2206 evaluateConstructorFieldInitializers(constructor, constructorList); | 2254 evaluateConstructorFieldInitializers(constructor, constructorList); |
| 2255 irBuilder.leaveInitializers(); |
| 2207 | 2256 |
| 2208 // All parameters in all constructors are now bound in the environment. | 2257 // All parameters in all constructors are now bound in the environment. |
| 2209 // BoxLocals for captured parameters are also in the environment. | 2258 // BoxLocals for captured parameters are also in the environment. |
| 2210 // The initial value of all fields are now bound in [fieldValues]. | 2259 // The initial value of all fields are now bound in [fieldValues]. |
| 2211 | 2260 |
| 2212 // --- Step 2: create the object --- | 2261 // --- Step 2: create the object --- |
| 2213 // Get the initial field values in the canonical order. | 2262 // Get the initial field values in the canonical order. |
| 2214 List<ir.Primitive> instanceArguments = <ir.Primitive>[]; | 2263 List<ir.Primitive> instanceArguments = <ir.Primitive>[]; |
| 2215 classElement.forEachInstanceField((ClassElement c, FieldElement field) { | 2264 classElement.forEachInstanceField((ClassElement c, FieldElement field) { |
| 2216 ir.Primitive value = fieldValues[field]; | 2265 ir.Primitive value = fieldValues[field]; |
| 2217 if (value != null) { | 2266 if (value != null) { |
| 2218 instanceArguments.add(fieldValues[field]); | 2267 instanceArguments.add(fieldValues[field]); |
| 2219 } else { | 2268 } else { |
| 2220 assert(Elements.isNativeOrExtendsNative(c)); | 2269 assert(Elements.isNativeOrExtendsNative(c)); |
| 2221 // Native fields are initialized elsewhere. | 2270 // Native fields are initialized elsewhere. |
| 2222 } | 2271 } |
| 2223 }, includeSuperAndInjectedMembers: true); | 2272 }, includeSuperAndInjectedMembers: true); |
| 2224 ir.Primitive instance = | 2273 ir.Primitive instance = new ir.CreateInstance( |
| 2225 new ir.CreateInstance(classElement, instanceArguments); | 2274 classElement, |
| 2275 instanceArguments, |
| 2276 typeInformation); |
| 2226 irBuilder.add(new ir.LetPrim(instance)); | 2277 irBuilder.add(new ir.LetPrim(instance)); |
| 2227 | 2278 |
| 2228 // --- Step 3: call constructor bodies --- | 2279 // --- Step 3: call constructor bodies --- |
| 2229 for (ConstructorElement target in constructorList) { | 2280 for (ConstructorElement target in constructorList) { |
| 2230 ConstructorBodyElement bodyElement = getConstructorBody(target); | 2281 ConstructorBodyElement bodyElement = getConstructorBody(target); |
| 2231 if (bodyElement == null) continue; // Skip if constructor has no body. | 2282 if (bodyElement == null) continue; // Skip if constructor has no body. |
| 2232 List<ir.Primitive> bodyArguments = <ir.Primitive>[]; | 2283 List<ir.Primitive> bodyArguments = <ir.Primitive>[]; |
| 2233 for (Local param in getConstructorBodyParameters(bodyElement)) { | 2284 for (Local param in getConstructorBodyParameters(bodyElement)) { |
| 2234 bodyArguments.add(irBuilder.environment.lookup(param)); | 2285 bodyArguments.add(irBuilder.environment.lookup(param)); |
| 2235 } | 2286 } |
| (...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 | 2500 /// This function is invoked from one or more "factory" constructors built by |
| 2450 /// [buildConstructor]. | 2501 /// [buildConstructor]. |
| 2451 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { | 2502 ir.FunctionDefinition buildConstructorBody(ConstructorBodyElement body) { |
| 2452 ConstructorElement constructor = body.constructor; | 2503 ConstructorElement constructor = body.constructor; |
| 2453 ast.FunctionExpression node = constructor.node; | 2504 ast.FunctionExpression node = constructor.node; |
| 2454 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( | 2505 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( |
| 2455 constructor, | 2506 constructor, |
| 2456 node, | 2507 node, |
| 2457 elements); | 2508 elements); |
| 2458 | 2509 |
| 2459 JsIrBuilder builder = | 2510 JsIrBuilder builder = getBuilderFor(body); |
| 2460 new JsIrBuilder(compiler.backend.constantSystem, body); | |
| 2461 | 2511 |
| 2462 return withBuilder(builder, () { | 2512 return withBuilder(builder, () { |
| 2463 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), | 2513 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), |
| 2464 getClosureScopeForNode(node)); | 2514 getClosureScopeForNode(node)); |
| 2465 visit(node.body); | 2515 visit(node.body); |
| 2466 return irBuilder.makeFunctionDefinition([]); | 2516 return irBuilder.makeFunctionDefinition([]); |
| 2467 }); | 2517 }); |
| 2468 } | 2518 } |
| 2469 | 2519 |
| 2470 ir.FunctionDefinition buildFunction(FunctionElement element) { | 2520 ir.FunctionDefinition buildFunction(FunctionElement element) { |
| 2471 assert(invariant(element, element.isImplementation)); | 2521 assert(invariant(element, element.isImplementation)); |
| 2472 ast.FunctionExpression node = element.node; | 2522 ast.FunctionExpression node = element.node; |
| 2473 | 2523 |
| 2474 assert(!element.isSynthesized); | 2524 assert(!element.isSynthesized); |
| 2475 assert(node != null); | 2525 assert(node != null); |
| 2476 assert(elements[node] != null); | 2526 assert(elements[node] != null); |
| 2477 | 2527 |
| 2478 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( | 2528 closureMap = compiler.closureToClassMapper.computeClosureToClassMapping( |
| 2479 element, | 2529 element, |
| 2480 node, | 2530 node, |
| 2481 elements); | 2531 elements); |
| 2482 IrBuilder builder = | 2532 IrBuilder builder = getBuilderFor(element); |
| 2483 new JsIrBuilder(compiler.backend.constantSystem, element); | |
| 2484 return withBuilder(builder, () => _makeFunctionBody(element, node)); | 2533 return withBuilder(builder, () => _makeFunctionBody(element, node)); |
| 2485 } | 2534 } |
| 2486 | 2535 |
| 2487 /// Creates a primitive for the default value of [parameter]. | 2536 /// Creates a primitive for the default value of [parameter]. |
| 2488 ir.Primitive translateDefaultValue(ParameterElement parameter) { | 2537 ir.Primitive translateDefaultValue(ParameterElement parameter) { |
| 2489 if (parameter.initializer == null) { | 2538 if (parameter.initializer == null) { |
| 2490 return irBuilder.buildNullLiteral(); | 2539 return irBuilder.buildNullLiteral(); |
| 2491 } else { | 2540 } else { |
| 2492 return inlineConstant(parameter.executableContext, parameter.initializer); | 2541 return inlineConstant(parameter.executableContext, parameter.initializer); |
| 2493 } | 2542 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2555 int nameIndex = selector.namedArguments.indexOf(argName); | 2604 int nameIndex = selector.namedArguments.indexOf(argName); |
| 2556 int translatedIndex = selector.positionalArgumentCount + nameIndex; | 2605 int translatedIndex = selector.positionalArgumentCount + nameIndex; |
| 2557 result.add(arguments[translatedIndex]); | 2606 result.add(arguments[translatedIndex]); |
| 2558 } | 2607 } |
| 2559 return result; | 2608 return result; |
| 2560 } | 2609 } |
| 2561 | 2610 |
| 2562 @override | 2611 @override |
| 2563 ir.Primitive buildReifyTypeVariable(ir.Primitive target, | 2612 ir.Primitive buildReifyTypeVariable(ir.Primitive target, |
| 2564 TypeVariableType variable) { | 2613 TypeVariableType variable) { |
| 2565 ir.Primitive typeArgument = new ir.ReadTypeVariable(variable, target); | 2614 ir.Primitive typeArgument = |
| 2566 irBuilder.add(new ir.LetPrim(typeArgument)); | 2615 irBuilder.buildTypeVariableAccess(target, variable); |
| 2616 |
| 2567 ir.Primitive type = new ir.ReifyRuntimeType(typeArgument); | 2617 ir.Primitive type = new ir.ReifyRuntimeType(typeArgument); |
| 2568 irBuilder.add(new ir.LetPrim(type)); | 2618 irBuilder.add(new ir.LetPrim(type)); |
| 2569 return type; | 2619 return type; |
| 2570 } | 2620 } |
| 2571 } | 2621 } |
| 2572 | 2622 |
| 2573 /// Interface for generating [SourceInformation] for the CPS. | 2623 /// Interface for generating [SourceInformation] for the CPS. |
| 2574 class SourceInformationBuilder { | 2624 class SourceInformationBuilder { |
| 2575 const SourceInformationBuilder(); | 2625 const SourceInformationBuilder(); |
| 2576 | 2626 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2603 SourceInformation buildCall(ast.Node node) { | 2653 SourceInformation buildCall(ast.Node node) { |
| 2604 return new PositionSourceInformation( | 2654 return new PositionSourceInformation( |
| 2605 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); | 2655 new TokenSourceLocation(sourceFile, node.getBeginToken(), name)); |
| 2606 } | 2656 } |
| 2607 | 2657 |
| 2608 @override | 2658 @override |
| 2609 SourceInformationBuilder forContext(AstElement element) { | 2659 SourceInformationBuilder forContext(AstElement element) { |
| 2610 return new PositionSourceInformationBuilder(element); | 2660 return new PositionSourceInformationBuilder(element); |
| 2611 } | 2661 } |
| 2612 } | 2662 } |
| OLD | NEW |