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

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

Issue 1136843006: dart2js cps: Access to lazily initialized fields. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase Created 5 years, 7 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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 /// Normalizes the argument list of a dynamic invocation (i.e. where the 215 /// Normalizes the argument list of a dynamic invocation (i.e. where the
216 /// target element is unknown). 216 /// target element is unknown).
217 /// 217 ///
218 /// For the JS backend, normalizes order of named arguments. 218 /// For the JS backend, normalizes order of named arguments.
219 /// 219 ///
220 /// For the Dart backend, returns [arguments]. 220 /// For the Dart backend, returns [arguments].
221 List<ir.Primitive> normalizeDynamicArguments( 221 List<ir.Primitive> normalizeDynamicArguments(
222 CallStructure callStructure, 222 CallStructure callStructure,
223 List<ir.Primitive> arguments); 223 List<ir.Primitive> arguments);
224 224
225 /// Read the value of [field].
226 ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src);
227
225 /// Creates a [TypedSelector] variant of [newSelector] using the type of 228 /// Creates a [TypedSelector] variant of [newSelector] using the type of
226 /// [oldSelector], if available. 229 /// [oldSelector], if available.
227 /// 230 ///
228 /// This is needed to preserve inferred receiver types when creating new 231 /// This is needed to preserve inferred receiver types when creating new
229 /// selectors. 232 /// selectors.
230 Selector useSelectorType(Selector newSelector, Selector oldSelector) { 233 Selector useSelectorType(Selector newSelector, Selector oldSelector) {
231 // TODO(asgerf,johnniwinther): This works but it is brittle. 234 // TODO(asgerf,johnniwinther): This works but it is brittle.
232 // We should decouple selectors from inferred receiver type masks. 235 // We should decouple selectors from inferred receiver type masks.
233 // TODO(asgerf): Use this whenever we create a selector for a dynamic call. 236 // TODO(asgerf): Use this whenever we create a selector for a dynamic call.
234 if (oldSelector is TypedSelector) { 237 if (oldSelector is TypedSelector) {
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 751
749 @override 752 @override
750 ir.Primitive visitLocalFunctionGet( 753 ir.Primitive visitLocalFunctionGet(
751 ast.Send node, 754 ast.Send node,
752 LocalFunctionElement function, 755 LocalFunctionElement function,
753 _) { 756 _) {
754 return irBuilder.buildLocalFunctionGet(function); 757 return irBuilder.buildLocalFunctionGet(function);
755 } 758 }
756 759
757 @override 760 @override
758 ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) {
759 return field.isConst
760 ? irBuilder.buildConstant(getConstantForVariable(field))
761 : irBuilder.buildStaticFieldGet(field,
762 sourceInformation: sourceInformationBuilder.buildGet(node));
763 }
764
765 @override
766 ir.Primitive handleStaticFunctionGet( 761 ir.Primitive handleStaticFunctionGet(
767 ast.Send node, 762 ast.Send node,
768 MethodElement function, 763 MethodElement function,
769 _) { 764 _) {
770 // TODO(karlklose): support foreign functions. 765 // TODO(karlklose): support foreign functions.
771 if (function.isForeign(compiler.backend)) { 766 if (function.isForeign(compiler.backend)) {
772 return giveup(node, 'handleStaticFunctionGet: foreign: $function'); 767 return giveup(node, 'handleStaticFunctionGet: foreign: $function');
773 } 768 }
774 return irBuilder.buildStaticFunctionGet(function); 769 return irBuilder.buildStaticFunctionGet(function);
775 } 770 }
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 ast.Send node, 1076 ast.Send node,
1082 LocalFunctionElement function, 1077 LocalFunctionElement function,
1083 ast.NodeList arguments, 1078 ast.NodeList arguments,
1084 CallStructure callStructure, 1079 CallStructure callStructure,
1085 _) { 1080 _) {
1086 return irBuilder.buildLocalFunctionInvocation(function, callStructure, 1081 return irBuilder.buildLocalFunctionInvocation(function, callStructure,
1087 translateDynamicArguments(arguments, callStructure)); 1082 translateDynamicArguments(arguments, callStructure));
1088 } 1083 }
1089 1084
1090 @override 1085 @override
1086 ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) {
1087 return buildStaticFieldGet(field, sourceInformationBuilder.buildGet(node));
1088 }
1089
1090 @override
1091 ir.Primitive handleStaticFieldInvoke( 1091 ir.Primitive handleStaticFieldInvoke(
1092 ast.Send node, 1092 ast.Send node,
1093 FieldElement field, 1093 FieldElement field,
1094 ast.NodeList arguments, 1094 ast.NodeList arguments,
1095 CallStructure callStructure, 1095 CallStructure callStructure,
1096 _) { 1096 _) {
1097 ir.Primitive target = irBuilder.buildStaticFieldGet(field); 1097 SourceInformation src = sourceInformationBuilder.buildGet(node);
1098 ir.Primitive target = buildStaticFieldGet(field, src);
1098 return irBuilder.buildCallInvocation(target, 1099 return irBuilder.buildCallInvocation(target,
1099 callStructure, 1100 callStructure,
1100 translateDynamicArguments(arguments, callStructure)); 1101 translateDynamicArguments(arguments, callStructure));
1101 } 1102 }
1102 1103
1103 @override 1104 @override
1104 ir.Primitive handleStaticFunctionInvoke( 1105 ir.Primitive handleStaticFunctionInvoke(
1105 ast.Send node, 1106 ast.Send node,
1106 MethodElement function, 1107 MethodElement function,
1107 ast.NodeList arguments, 1108 ast.NodeList arguments,
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
1418 return irBuilder.buildLocalVariableSet(element, visit(rhs)); 1419 return irBuilder.buildLocalVariableSet(element, visit(rhs));
1419 } 1420 }
1420 1421
1421 @override 1422 @override
1422 ir.Primitive handleStaticFieldCompound( 1423 ir.Primitive handleStaticFieldCompound(
1423 ast.Send node, 1424 ast.Send node,
1424 FieldElement field, 1425 FieldElement field,
1425 op.AssignmentOperator operator, 1426 op.AssignmentOperator operator,
1426 ast.Node rhs, 1427 ast.Node rhs,
1427 _) { 1428 _) {
1429 SourceInformation src = sourceInformationBuilder.buildGet(node);
1428 return translateCompound( 1430 return translateCompound(
1429 getValue: () => irBuilder.buildStaticFieldGet(field), 1431 getValue: () => buildStaticFieldGet(field, src),
1430 operator: operator, 1432 operator: operator,
1431 rhs: rhs, 1433 rhs: rhs,
1432 setValue: (ir.Primitive result) { 1434 setValue: (ir.Primitive result) {
1433 irBuilder.buildStaticFieldSet(field, result); 1435 irBuilder.buildStaticFieldSet(field, result);
1434 }); 1436 });
1435 } 1437 }
1436 1438
1437 @override 1439 @override
1438 ir.Primitive handleStaticFieldPostfixPrefix( 1440 ir.Primitive handleStaticFieldPostfixPrefix(
1439 ast.Send node, 1441 ast.Send node,
1440 FieldElement field, 1442 FieldElement field,
1441 op.IncDecOperator operator, 1443 op.IncDecOperator operator,
1442 arg, 1444 arg,
1443 {bool isPrefix}) { 1445 {bool isPrefix}) {
1446 SourceInformation src = sourceInformationBuilder.buildGet(node);
1444 return translatePrefixPostfix( 1447 return translatePrefixPostfix(
1445 getValue: () => irBuilder.buildStaticFieldGet(field), 1448 getValue: () => buildStaticFieldGet(field, src),
1446 operator: operator, 1449 operator: operator,
1447 setValue: (ir.Primitive result) { 1450 setValue: (ir.Primitive result) {
1448 irBuilder.buildStaticFieldSet(field, result); 1451 irBuilder.buildStaticFieldSet(field, result);
1449 }, 1452 },
1450 isPrefix: isPrefix); 1453 isPrefix: isPrefix);
1451 } 1454 }
1452 1455
1453 @override 1456 @override
1454 ir.Primitive handleStaticFieldSet( 1457 ir.Primitive handleStaticFieldSet(
1455 ast.SendSet node, 1458 ast.SendSet node,
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after
2319 Selector selector = new Selector.setter(parameter.name, null); 2322 Selector selector = new Selector.setter(parameter.name, null);
2320 return buildStaticNoSuchMethod(selector, [visit(rhs)]); 2323 return buildStaticNoSuchMethod(selector, [visit(rhs)]);
2321 } 2324 }
2322 2325
2323 @override 2326 @override
2324 ir.Primitive errorFinalStaticFieldCompound( 2327 ir.Primitive errorFinalStaticFieldCompound(
2325 ast.Send node, 2328 ast.Send node,
2326 FieldElement field, 2329 FieldElement field,
2327 op.AssignmentOperator operator, 2330 op.AssignmentOperator operator,
2328 ast.Node rhs, _) { 2331 ast.Node rhs, _) {
2332 SourceInformation src = sourceInformationBuilder.buildGet(node);
2329 return translateCompound( 2333 return translateCompound(
2330 getValue: () => irBuilder.buildStaticFieldGet(field), 2334 getValue: () => buildStaticFieldGet(field, src),
2331 operator: operator, 2335 operator: operator,
2332 rhs: rhs, 2336 rhs: rhs,
2333 setValue: (value) => buildStaticNoSuchMethod( 2337 setValue: (value) => buildStaticNoSuchMethod(
2334 new Selector.setter(field.name, field.library), [value])); 2338 new Selector.setter(field.name, field.library), [value]));
2335 } 2339 }
2336 2340
2337 @override 2341 @override
2338 ir.Primitive errorFinalStaticFieldSet( 2342 ir.Primitive errorFinalStaticFieldSet(
2339 ast.SendSet node, 2343 ast.SendSet node,
2340 FieldElement field, 2344 FieldElement field,
(...skipping 30 matching lines...) Expand all
2371 node); 2375 node);
2372 return buildInstanceNoSuchMethod(selector, [visit(rhs)]); 2376 return buildInstanceNoSuchMethod(selector, [visit(rhs)]);
2373 } 2377 }
2374 2378
2375 @override 2379 @override
2376 ir.Primitive errorFinalTopLevelFieldCompound( 2380 ir.Primitive errorFinalTopLevelFieldCompound(
2377 ast.Send node, 2381 ast.Send node,
2378 FieldElement field, 2382 FieldElement field,
2379 op.AssignmentOperator operator, 2383 op.AssignmentOperator operator,
2380 ast.Node rhs, _) { 2384 ast.Node rhs, _) {
2385 SourceInformation src = sourceInformationBuilder.buildGet(node);
2381 return translateCompound( 2386 return translateCompound(
2382 getValue: () => irBuilder.buildStaticFieldGet(field), 2387 getValue: () => buildStaticFieldGet(field, src),
2383 operator: operator, 2388 operator: operator,
2384 rhs: rhs, 2389 rhs: rhs,
2385 setValue: (value) => buildStaticNoSuchMethod( 2390 setValue: (value) => buildStaticNoSuchMethod(
2386 new Selector.setter(field.name, field.library), [value])); 2391 new Selector.setter(field.name, field.library), [value]));
2387 } 2392 }
2388 2393
2389 @override 2394 @override
2390 ir.Primitive errorFinalTopLevelFieldSet( 2395 ir.Primitive errorFinalTopLevelFieldSet(
2391 ast.SendSet node, 2396 ast.SendSet node,
2392 FieldElement field, 2397 FieldElement field,
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
2967 2972
2968 @override 2973 @override
2969 ir.Primitive buildRuntimeError(String message) { 2974 ir.Primitive buildRuntimeError(String message) {
2970 return giveup(null, 'Build runtime error: $message'); 2975 return giveup(null, 'Build runtime error: $message');
2971 } 2976 }
2972 2977
2973 @override 2978 @override
2974 ir.Primitive buildAbstractClassInstantiationError(ClassElement element) { 2979 ir.Primitive buildAbstractClassInstantiationError(ClassElement element) {
2975 return giveup(null, 'Abstract class instantiation: ${element.name}'); 2980 return giveup(null, 'Abstract class instantiation: ${element.name}');
2976 } 2981 }
2982
2983 ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) {
2984 return irBuilder.buildStaticFieldLazyGet(field, src);
2985 }
2977 } 2986 }
2978 2987
2979 /// The [IrBuilder]s view on the information about the program that has been 2988 /// The [IrBuilder]s view on the information about the program that has been
2980 /// computed in resolution and and type interence. 2989 /// computed in resolution and and type interence.
2981 class GlobalProgramInformation { 2990 class GlobalProgramInformation {
2982 final Compiler _compiler; 2991 final Compiler _compiler;
2983 JavaScriptBackend get _backend => _compiler.backend; 2992 JavaScriptBackend get _backend => _compiler.backend;
2984 2993
2985 GlobalProgramInformation(this._compiler); 2994 GlobalProgramInformation(this._compiler);
2986 2995
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
3105 case ElementKind.GENERATIVE_CONSTRUCTOR_BODY: 3114 case ElementKind.GENERATIVE_CONSTRUCTOR_BODY:
3106 root = buildConstructorBody(element); 3115 root = buildConstructorBody(element);
3107 break; 3116 break;
3108 3117
3109 case ElementKind.FUNCTION: 3118 case ElementKind.FUNCTION:
3110 case ElementKind.GETTER: 3119 case ElementKind.GETTER:
3111 case ElementKind.SETTER: 3120 case ElementKind.SETTER:
3112 root = buildFunction(element); 3121 root = buildFunction(element);
3113 break; 3122 break;
3114 3123
3124 case ElementKind.FIELD:
3125 if (Elements.isStaticOrTopLevel(element)) {
3126 root = buildStaticFieldInitializer(element);
3127 } else {
3128 // Instance field initializers are inlined in the constructor,
3129 // so we shouldn't need to build anything here.
3130 // TODO(asgerf): But what should we return?
3131 return null;
3132 }
3133 break;
3134
3115 default: 3135 default:
3116 compiler.internalError(element, "Unexpected element type $element"); 3136 compiler.internalError(element, "Unexpected element type $element");
3117 } 3137 }
3118 new CleanupPass().visit(root); 3138 new CleanupPass().visit(root);
3119 return root; 3139 return root;
3120 }); 3140 });
3121 } 3141 }
3122 3142
3143 ir.FunctionDefinition buildStaticFieldInitializer(FieldElement element) {
3144 if (!backend.constants.lazyStatics.contains(element)) {
3145 return null; // Nothing to do.
3146 }
3147 closureClassMap =
3148 compiler.closureToClassMapper.computeClosureToClassMapping(
3149 element,
3150 element.node,
3151 elements);
3152 IrBuilder builder = getBuilderFor(element);
3153 return withBuilder(builder, () {
3154 ir.Primitive initialValue = visit(element.initializer);
3155 irBuilder.buildReturn(initialValue);
3156 return irBuilder.makeLazyFieldInitializer();
3157 });
3158 }
3159
3123 /// Builds the IR for an [expression] taken from a different [context]. 3160 /// Builds the IR for an [expression] taken from a different [context].
3124 /// 3161 ///
3125 /// Such expressions need to be compiled with a different [sourceFile] and 3162 /// Such expressions need to be compiled with a different [sourceFile] and
3126 /// [elements] mapping. 3163 /// [elements] mapping.
3127 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) { 3164 ir.Primitive inlineExpression(AstElement context, ast.Expression expression) {
3128 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor( 3165 JsIrBuilderVisitor visitor = new JsIrBuilderVisitor(
3129 context.resolvedAst.elements, 3166 context.resolvedAst.elements,
3130 compiler, 3167 compiler,
3131 sourceInformationBuilder.forContext(context)); 3168 sourceInformationBuilder.forContext(context));
3132 return visitor.withBuilder(irBuilder, () => visitor.visit(expression)); 3169 return visitor.withBuilder(irBuilder, () => visitor.visit(expression));
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after
3630 [irBuilder.buildStringConstant(message)]); 3667 [irBuilder.buildStringConstant(message)]);
3631 } 3668 }
3632 3669
3633 @override 3670 @override
3634 ir.Primitive buildAbstractClassInstantiationError(ClassElement element) { 3671 ir.Primitive buildAbstractClassInstantiationError(ClassElement element) {
3635 return irBuilder.buildStaticFunctionInvocation( 3672 return irBuilder.buildStaticFunctionInvocation(
3636 backend.getThrowAbstractClassInstantiationError(), 3673 backend.getThrowAbstractClassInstantiationError(),
3637 new CallStructure.unnamed(1), 3674 new CallStructure.unnamed(1),
3638 [irBuilder.buildStringConstant(element.name)]); 3675 [irBuilder.buildStringConstant(element.name)]);
3639 } 3676 }
3677
3678 @override
3679 ir.Primitive handleStaticFieldGet(ast.Send node, FieldElement field, _) {
3680 SourceInformation src = sourceInformationBuilder.buildGet(node);
3681 return buildStaticFieldGet(field, src);
3682 }
3683
3684 ir.Primitive buildStaticFieldGet(FieldElement field, SourceInformation src) {
3685 ConstantExpression constant =
3686 backend.constants.getConstantForVariable(field);
3687 if (constant != null && !field.isAssignable) {
3688 return irBuilder.buildConstant(constant);
3689 } else if (backend.constants.lazyStatics.contains(field)) {
3690 return irBuilder.buildStaticFieldLazyGet(field, src);
3691 } else {
3692 return irBuilder.buildStaticFieldGet(field, src);
3693 }
3694 }
3640 } 3695 }
3641 3696
3642 /// Perform simple post-processing on the initial CPS-translated root term. 3697 /// Perform simple post-processing on the initial CPS-translated root term.
3643 /// 3698 ///
3644 /// This pass performs backend-independent post-processing on the translated 3699 /// This pass performs backend-independent post-processing on the translated
3645 /// term. It is implemented separately from the optimization passes because 3700 /// term. It is implemented separately from the optimization passes because
3646 /// it is required for correctness of the implementation. 3701 /// it is required for correctness of the implementation.
3647 /// 3702 ///
3648 /// It performs the following translations: 3703 /// It performs the following translations:
3649 /// - Replace [ir.LetPrim] binding a [ir.NonTailThrow] with a [ir.Throw] 3704 /// - Replace [ir.LetPrim] binding a [ir.NonTailThrow] with a [ir.Throw]
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
3702 node.body = replacementFor(node.body); 3757 node.body = replacementFor(node.body);
3703 } 3758 }
3704 } 3759 }
3705 3760
3706 /// Visit a just-deleted subterm and unlink all [Reference]s in it. 3761 /// Visit a just-deleted subterm and unlink all [Reference]s in it.
3707 class RemovalVisitor extends ir.RecursiveVisitor { 3762 class RemovalVisitor extends ir.RecursiveVisitor {
3708 processReference(ir.Reference reference) { 3763 processReference(ir.Reference reference) {
3709 reference.unlink(); 3764 reference.unlink();
3710 } 3765 }
3711 } 3766 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698