| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 bailoutMessage = builder.bailoutMessage; | 73 bailoutMessage = builder.bailoutMessage; |
| 74 } else if (builderCallback != null) { | 74 } else if (builderCallback != null) { |
| 75 builderCallback(element, irNode); | 75 builderCallback(element, irNode); |
| 76 } | 76 } |
| 77 return irNode; | 77 return irNode; |
| 78 }); | 78 }); |
| 79 }); | 79 }); |
| 80 } | 80 } |
| 81 } | 81 } |
| 82 | 82 |
| 83 | 83 /// Translates the frontend AST of a method to its CPS IR. |
| 84 /// A tree visitor that builds [ir.Node]s. | |
| 85 /// | 84 /// |
| 86 /// The visit methods add statements using the [irBuilder] and return the last | 85 /// The visitor has an [IrBuilder] which contains an IR fragment to build upon |
| 87 /// added statement for trees that represent expressions. | 86 /// and the current reaching definition of local variables. |
| 88 /// | 87 /// |
| 88 /// Visiting a statement or expression extends the IR builder's fragment. |
| 89 /// For expressions, the primitive holding the resulting value is returned. |
| 90 /// For statements, `null` is returned. |
| 89 // TODO(johnniwinther): Implement [SemanticDeclVisitor]. | 91 // TODO(johnniwinther): Implement [SemanticDeclVisitor]. |
| 90 abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> | 92 abstract class IrBuilderVisitor extends ast.Visitor<ir.Primitive> |
| 91 with IrBuilderMixin<ast.Node>, | 93 with IrBuilderMixin<ast.Node>, |
| 92 SemanticSendResolvedMixin<ir.Primitive, dynamic>, | 94 SemanticSendResolvedMixin<ir.Primitive, dynamic>, |
| 93 SendResolverMixin, | 95 SendResolverMixin, |
| 94 BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>, | 96 BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>, |
| 95 BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>, | 97 BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>, |
| 96 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, | 98 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, |
| 97 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, | 99 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, |
| 98 BaseImplementationOfNewMixin<ir.Primitive, dynamic>, | 100 BaseImplementationOfNewMixin<ir.Primitive, dynamic>, |
| (...skipping 2028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2127 | 2129 |
| 2128 DartType unaliasType(DartType type) => type.unalias(_compiler); | 2130 DartType unaliasType(DartType type) => type.unalias(_compiler); |
| 2129 | 2131 |
| 2130 TypeMask getTypeMaskForForeign(NativeBehavior behavior) { | 2132 TypeMask getTypeMaskForForeign(NativeBehavior behavior) { |
| 2131 return TypeMaskFactory.fromNativeBehavior(behavior, _compiler); | 2133 return TypeMaskFactory.fromNativeBehavior(behavior, _compiler); |
| 2132 } | 2134 } |
| 2133 } | 2135 } |
| 2134 | 2136 |
| 2135 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. | 2137 /// IR builder specific to the JavaScript backend, coupled to the [JsIrBuilder]. |
| 2136 class JsIrBuilderVisitor extends IrBuilderVisitor { | 2138 class JsIrBuilderVisitor extends IrBuilderVisitor { |
| 2137 /// Promote the type of [irBuilder] to [JsIrBuilder]. | |
| 2138 JsIrBuilder get irBuilder => super.irBuilder; | |
| 2139 | |
| 2140 JavaScriptBackend get backend => compiler.backend; | 2139 JavaScriptBackend get backend => compiler.backend; |
| 2141 | 2140 |
| 2142 /// Result of closure conversion for the current body of code. | 2141 /// Result of closure conversion for the current body of code. |
| 2143 /// | 2142 /// |
| 2144 /// Will be initialized upon entering the body of a function. | 2143 /// Will be initialized upon entering the body of a function. |
| 2145 /// It is computed by the [ClosureTranslator]. | 2144 /// It is computed by the [ClosureTranslator]. |
| 2146 ClosureClassMap closureClassMap; | 2145 ClosureClassMap closureClassMap; |
| 2147 | 2146 |
| 2148 JsIrBuilderVisitor(TreeElements elements, | 2147 JsIrBuilderVisitor(TreeElements elements, |
| 2149 Compiler compiler, | 2148 Compiler compiler, |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2309 | 2308 |
| 2310 /// Builds the IR for a constant taken from a different [context]. | 2309 /// Builds the IR for a constant taken from a different [context]. |
| 2311 /// | 2310 /// |
| 2312 /// Such constants need to be compiled with a different [sourceFile] and | 2311 /// Such constants need to be compiled with a different [sourceFile] and |
| 2313 /// [elements] mapping. | 2312 /// [elements] mapping. |
| 2314 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) { | 2313 ir.Primitive inlineConstant(AstElement context, ast.Expression exp) { |
| 2315 JsIrBuilderVisitor visitor = makeVisitorForContext(context); | 2314 JsIrBuilderVisitor visitor = makeVisitorForContext(context); |
| 2316 return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp)); | 2315 return visitor.withBuilder(irBuilder, () => visitor.translateConstant(exp)); |
| 2317 } | 2316 } |
| 2318 | 2317 |
| 2319 JsIrBuilder getBuilderFor(Element element) { | 2318 IrBuilder getBuilderFor(Element element) { |
| 2320 return new JsIrBuilder( | 2319 return new IrBuilder( |
| 2321 new GlobalProgramInformation(compiler), | 2320 new GlobalProgramInformation(compiler), |
| 2322 compiler.backend.constants, | 2321 compiler.backend.constants, |
| 2323 element); | 2322 element); |
| 2324 } | 2323 } |
| 2325 | 2324 |
| 2326 /// Builds the IR for a given constructor. | 2325 /// Builds the IR for a given constructor. |
| 2327 /// | 2326 /// |
| 2328 /// 1. Computes the type held in all own or "inherited" type variables. | 2327 /// 1. Computes the type held in all own or "inherited" type variables. |
| 2329 /// 2. Evaluates all own or inherited field initializers. | 2328 /// 2. Evaluates all own or inherited field initializers. |
| 2330 /// 3. Creates the object and assigns its fields and runtime type. | 2329 /// 3. Creates the object and assigns its fields and runtime type. |
| 2331 /// 4. Calls constructor body and super constructor bodies. | 2330 /// 4. Calls constructor body and super constructor bodies. |
| 2332 /// 5. Returns the created object. | 2331 /// 5. Returns the created object. |
| 2333 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { | 2332 ir.FunctionDefinition buildConstructor(ConstructorElement constructor) { |
| 2334 // TODO(asgerf): Optimization: If constructor is redirecting, then just | 2333 // TODO(asgerf): Optimization: If constructor is redirecting, then just |
| 2335 // evaluate arguments and call the target constructor. | 2334 // evaluate arguments and call the target constructor. |
| 2336 constructor = constructor.implementation; | 2335 constructor = constructor.implementation; |
| 2337 ClassElement classElement = constructor.enclosingClass.implementation; | 2336 ClassElement classElement = constructor.enclosingClass.implementation; |
| 2338 | 2337 |
| 2339 JsIrBuilder builder = getBuilderFor(constructor); | 2338 IrBuilder builder = getBuilderFor(constructor); |
| 2340 | 2339 |
| 2341 final bool requiresTypeInformation = | 2340 final bool requiresTypeInformation = |
| 2342 builder.program.requiresRuntimeTypesFor(classElement); | 2341 builder.program.requiresRuntimeTypesFor(classElement); |
| 2343 | 2342 |
| 2344 return withBuilder(builder, () { | 2343 return withBuilder(builder, () { |
| 2345 // Setup parameters and create a box if anything is captured. | 2344 // Setup parameters and create a box if anything is captured. |
| 2346 List<Local> parameters = <Local>[]; | 2345 List<Local> parameters = <Local>[]; |
| 2347 constructor.functionSignature.orderedForEachParameter( | 2346 constructor.functionSignature.orderedForEachParameter( |
| 2348 (ParameterElement p) => parameters.add(p)); | 2347 (ParameterElement p) => parameters.add(p)); |
| 2349 | 2348 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2380 // This could be interleaved with field initialization, but we choose do | 2379 // This could be interleaved with field initialization, but we choose do |
| 2381 // get it out of the way here to avoid complications with mixins. | 2380 // get it out of the way here to avoid complications with mixins. |
| 2382 loadTypeVariablesForSuperClasses(classElement); | 2381 loadTypeVariablesForSuperClasses(classElement); |
| 2383 | 2382 |
| 2384 /// Maps each field from this class or a superclass to its initial value. | 2383 /// Maps each field from this class or a superclass to its initial value. |
| 2385 Map<FieldElement, ir.Primitive> fieldValues = | 2384 Map<FieldElement, ir.Primitive> fieldValues = |
| 2386 <FieldElement, ir.Primitive>{}; | 2385 <FieldElement, ir.Primitive>{}; |
| 2387 | 2386 |
| 2388 // -- Evaluate field initializers --- | 2387 // -- Evaluate field initializers --- |
| 2389 // Evaluate field initializers in constructor and super constructors. | 2388 // Evaluate field initializers in constructor and super constructors. |
| 2390 irBuilder.enterInitializers(); | |
| 2391 List<ConstructorElement> constructorList = <ConstructorElement>[]; | 2389 List<ConstructorElement> constructorList = <ConstructorElement>[]; |
| 2392 evaluateConstructorFieldInitializers( | 2390 evaluateConstructorFieldInitializers( |
| 2393 constructor, constructorList, fieldValues); | 2391 constructor, constructorList, fieldValues); |
| 2394 irBuilder.leaveInitializers(); | |
| 2395 | 2392 |
| 2396 // All parameters in all constructors are now bound in the environment. | 2393 // All parameters in all constructors are now bound in the environment. |
| 2397 // BoxLocals for captured parameters are also in the environment. | 2394 // BoxLocals for captured parameters are also in the environment. |
| 2398 // The initial value of all fields are now bound in [fieldValues]. | 2395 // The initial value of all fields are now bound in [fieldValues]. |
| 2399 | 2396 |
| 2400 // --- Create the object --- | 2397 // --- Create the object --- |
| 2401 // Get the initial field values in the canonical order. | 2398 // Get the initial field values in the canonical order. |
| 2402 List<ir.Primitive> instanceArguments = <ir.Primitive>[]; | 2399 List<ir.Primitive> instanceArguments = <ir.Primitive>[]; |
| 2403 classElement.forEachInstanceField((ClassElement c, FieldElement field) { | 2400 classElement.forEachInstanceField((ClassElement c, FieldElement field) { |
| 2404 ir.Primitive value = fieldValues[field]; | 2401 ir.Primitive value = fieldValues[field]; |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2726 | 2723 |
| 2727 // We compute variables boxed in mutable variables on entry to each try | 2724 // We compute variables boxed in mutable variables on entry to each try |
| 2728 // block, not including variables captured by a closure (which are boxed | 2725 // block, not including variables captured by a closure (which are boxed |
| 2729 // in the heap). This duplicates some of the work of closure conversion | 2726 // in the heap). This duplicates some of the work of closure conversion |
| 2730 // without directly using the results. This duplication is wasteful and | 2727 // without directly using the results. This duplication is wasteful and |
| 2731 // error-prone. | 2728 // error-prone. |
| 2732 // TODO(kmillikin): We should combine closure conversion and try/catch | 2729 // TODO(kmillikin): We should combine closure conversion and try/catch |
| 2733 // variable analysis in some way. | 2730 // variable analysis in some way. |
| 2734 DartCapturedVariables variables = _analyzeCapturedVariables(node); | 2731 DartCapturedVariables variables = _analyzeCapturedVariables(node); |
| 2735 tryStatements = variables.tryStatements; | 2732 tryStatements = variables.tryStatements; |
| 2736 JsIrBuilder builder = getBuilderFor(body); | 2733 IrBuilder builder = getBuilderFor(body); |
| 2737 | 2734 |
| 2738 return withBuilder(builder, () { | 2735 return withBuilder(builder, () { |
| 2739 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), | 2736 irBuilder.buildConstructorBodyHeader(getConstructorBodyParameters(body), |
| 2740 getClosureScopeForNode(node)); | 2737 getClosureScopeForNode(node)); |
| 2741 visit(node.body); | 2738 visit(node.body); |
| 2742 return irBuilder.makeFunctionDefinition(); | 2739 return irBuilder.makeFunctionDefinition(); |
| 2743 }); | 2740 }); |
| 2744 } | 2741 } |
| 2745 | 2742 |
| 2746 ir.FunctionDefinition buildFunction(FunctionElement element) { | 2743 ir.FunctionDefinition buildFunction(FunctionElement element) { |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3189 } | 3186 } |
| 3190 | 3187 |
| 3191 processSetStatic(ir.SetStatic node) { | 3188 processSetStatic(ir.SetStatic node) { |
| 3192 node.body = replacementFor(node.body); | 3189 node.body = replacementFor(node.body); |
| 3193 } | 3190 } |
| 3194 | 3191 |
| 3195 processContinuation(ir.Continuation node) { | 3192 processContinuation(ir.Continuation node) { |
| 3196 node.body = replacementFor(node.body); | 3193 node.body = replacementFor(node.body); |
| 3197 } | 3194 } |
| 3198 } | 3195 } |
| OLD | NEW |