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

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 1631803003: Fix building of closure type arguments (fixes #25543). (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 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
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | tests/language/language.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 #include "vm/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "lib/invocation_mirror.h" 7 #include "lib/invocation_mirror.h"
8 #include "vm/ast_printer.h" 8 #include "vm/ast_printer.h"
9 #include "vm/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after
1507 1507
1508 1508
1509 void EffectGraphVisitor::BuildTypecheckPushArguments( 1509 void EffectGraphVisitor::BuildTypecheckPushArguments(
1510 intptr_t token_pos, 1510 intptr_t token_pos,
1511 PushArgumentInstr** push_instantiator_type_arguments_result) { 1511 PushArgumentInstr** push_instantiator_type_arguments_result) {
1512 const Class& instantiator_class = Class::Handle( 1512 const Class& instantiator_class = Class::Handle(
1513 Z, owner()->function().Owner()); 1513 Z, owner()->function().Owner());
1514 // Since called only when type tested against is not instantiated. 1514 // Since called only when type tested against is not instantiated.
1515 ASSERT(instantiator_class.IsGeneric()); 1515 ASSERT(instantiator_class.IsGeneric());
1516 Value* instantiator_type_arguments = NULL; 1516 Value* instantiator_type_arguments = NULL;
1517 Value* instantiator = BuildInstantiator(token_pos, instantiator_class); 1517 Value* instantiator = BuildInstantiator(token_pos);
1518 if (instantiator == NULL) { 1518 if (instantiator == NULL) {
1519 // No instantiator when inside factory. 1519 // No instantiator when inside factory.
1520 instantiator_type_arguments = 1520 instantiator_type_arguments =
1521 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 1521 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
1522 } else { 1522 } else {
1523 instantiator_type_arguments = BuildInstantiatorTypeArguments( 1523 instantiator_type_arguments = BuildInstantiatorTypeArguments(
1524 token_pos, instantiator_class, instantiator); 1524 token_pos, instantiator_class, instantiator);
1525 } 1525 }
1526 *push_instantiator_type_arguments_result = 1526 *push_instantiator_type_arguments_result =
1527 PushArgument(instantiator_type_arguments); 1527 PushArgument(instantiator_type_arguments);
1528 } 1528 }
1529 1529
1530 1530
1531 1531
1532 void EffectGraphVisitor::BuildTypecheckArguments( 1532 void EffectGraphVisitor::BuildTypecheckArguments(
1533 intptr_t token_pos, 1533 intptr_t token_pos,
1534 Value** instantiator_type_arguments_result) { 1534 Value** instantiator_type_arguments_result) {
1535 Value* instantiator = NULL; 1535 Value* instantiator = NULL;
1536 Value* instantiator_type_arguments = NULL; 1536 Value* instantiator_type_arguments = NULL;
1537 const Class& instantiator_class = Class::Handle( 1537 const Class& instantiator_class = Class::Handle(
1538 Z, owner()->function().Owner()); 1538 Z, owner()->function().Owner());
1539 // Since called only when type tested against is not instantiated. 1539 // Since called only when type tested against is not instantiated.
1540 ASSERT(instantiator_class.IsGeneric()); 1540 ASSERT(instantiator_class.IsGeneric());
1541 instantiator = BuildInstantiator(token_pos, instantiator_class); 1541 instantiator = BuildInstantiator(token_pos);
1542 if (instantiator == NULL) { 1542 if (instantiator == NULL) {
1543 // No instantiator when inside factory. 1543 // No instantiator when inside factory.
1544 instantiator_type_arguments = 1544 instantiator_type_arguments =
1545 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); 1545 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL);
1546 } else { 1546 } else {
1547 instantiator_type_arguments = BuildInstantiatorTypeArguments( 1547 instantiator_type_arguments = BuildInstantiatorTypeArguments(
1548 token_pos, instantiator_class, instantiator); 1548 token_pos, instantiator_class, instantiator);
1549 } 1549 }
1550 *instantiator_type_arguments_result = instantiator_type_arguments; 1550 *instantiator_type_arguments_result = instantiator_type_arguments;
1551 } 1551 }
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after
2535 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val, 2535 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val,
2536 node->token_pos()); 2536 node->token_pos());
2537 // Store type arguments if scope class is generic. 2537 // Store type arguments if scope class is generic.
2538 const FunctionType& function_type = 2538 const FunctionType& function_type =
2539 FunctionType::ZoneHandle(Z, function.SignatureType()); 2539 FunctionType::ZoneHandle(Z, function.SignatureType());
2540 const Class& scope_cls = Class::ZoneHandle(Z, function_type.scope_class()); 2540 const Class& scope_cls = Class::ZoneHandle(Z, function_type.scope_class());
2541 if (scope_cls.IsGeneric()) { 2541 if (scope_cls.IsGeneric()) {
2542 ASSERT(function.Owner() == scope_cls.raw()); 2542 ASSERT(function.Owner() == scope_cls.raw());
2543 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var, 2543 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var,
2544 node->token_pos())); 2544 node->token_pos()));
2545 const Class& instantiator_class = Class::Handle(
2546 Z, owner()->function().Owner());
2545 Value* type_arguments = BuildInstantiatorTypeArguments(node->token_pos(), 2547 Value* type_arguments = BuildInstantiatorTypeArguments(node->token_pos(),
2546 scope_cls, 2548 instantiator_class,
2547 NULL); 2549 NULL);
2548 Do(new(Z) StoreInstanceFieldInstr(Closure::type_arguments_offset(), 2550 Do(new(Z) StoreInstanceFieldInstr(Closure::type_arguments_offset(),
2549 closure_tmp_val, 2551 closure_tmp_val,
2550 type_arguments, 2552 type_arguments,
2551 kEmitStoreBarrier, 2553 kEmitStoreBarrier,
2552 node->token_pos())); 2554 node->token_pos()));
2553 } 2555 }
2554 2556
2555 // Store function. 2557 // Store function.
2556 Value* closure_tmp_val = 2558 Value* closure_tmp_val =
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
2909 // t_n+1 <- ctor-arg 2911 // t_n+1 <- ctor-arg
2910 // t_n+2... <- constructor arguments start here 2912 // t_n+2... <- constructor arguments start here
2911 // StaticCall(constructor, t_n+1, t_n+2, ...) 2913 // StaticCall(constructor, t_n+1, t_n+2, ...)
2912 // No need to preserve allocated value (simpler than in ValueGraphVisitor). 2914 // No need to preserve allocated value (simpler than in ValueGraphVisitor).
2913 Value* allocated_value = BuildObjectAllocation(node); 2915 Value* allocated_value = BuildObjectAllocation(node);
2914 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); 2916 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value);
2915 BuildConstructorCall(node, push_allocated_value); 2917 BuildConstructorCall(node, push_allocated_value);
2916 } 2918 }
2917 2919
2918 2920
2919 Value* EffectGraphVisitor::BuildInstantiator(intptr_t token_pos, 2921 Value* EffectGraphVisitor::BuildInstantiator(intptr_t token_pos) {
2920 const Class& instantiator_class) {
2921 ASSERT(instantiator_class.IsGeneric());
2922 Function& outer_function = Function::Handle(Z, owner()->function().raw()); 2922 Function& outer_function = Function::Handle(Z, owner()->function().raw());
2923 while (outer_function.IsLocalFunction()) { 2923 while (outer_function.IsLocalFunction()) {
2924 outer_function = outer_function.parent_function(); 2924 outer_function = outer_function.parent_function();
2925 } 2925 }
2926 if (outer_function.IsFactory()) { 2926 if (outer_function.IsFactory()) {
2927 return NULL; 2927 return NULL;
2928 } 2928 }
2929 2929
2930 LocalVariable* instantiator = owner()->parsed_function().instantiator(); 2930 LocalVariable* instantiator = owner()->parsed_function().instantiator();
2931 ASSERT(instantiator != NULL); 2931 ASSERT(instantiator != NULL);
2932 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos)); 2932 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos));
2933 return result; 2933 return result;
2934 } 2934 }
2935 2935
2936 2936
2937 // 'expression_temp_var' may not be used inside this method if 'instantiator' 2937 // 'expression_temp_var' may not be used inside this method if 'instantiator'
2938 // is not NULL. 2938 // is not NULL.
2939 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( 2939 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments(
2940 intptr_t token_pos, 2940 intptr_t token_pos,
2941 const Class& instantiator_class, 2941 const Class& instantiator_class,
2942 Value* instantiator) { 2942 Value* instantiator) {
2943 if (instantiator_class.NumTypeParameters() == 0) { 2943 if (!instantiator_class.IsGeneric()) {
2944 // The type arguments are compile time constants. 2944 // The type arguments are compile time constants.
2945 TypeArguments& type_arguments = 2945 TypeArguments& type_arguments =
2946 TypeArguments::ZoneHandle(Z, TypeArguments::null()); 2946 TypeArguments::ZoneHandle(Z, TypeArguments::null());
2947 // Type is temporary. Only its type arguments are preserved. 2947 // Type is temporary. Only its type arguments are preserved.
2948 Type& type = Type::Handle( 2948 Type& type = Type::Handle(
2949 Z, 2949 Z,
2950 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew)); 2950 Type::New(instantiator_class, type_arguments, token_pos, Heap::kNew));
2951 type ^= ClassFinalizer::FinalizeType( 2951 type ^= ClassFinalizer::FinalizeType(
2952 instantiator_class, type, ClassFinalizer::kFinalize); 2952 instantiator_class, type, ClassFinalizer::kFinalize);
2953 ASSERT(!type.IsMalformedOrMalbounded()); 2953 ASSERT(!type.IsMalformedOrMalbounded());
2954 type_arguments = type.arguments(); 2954 type_arguments = type.arguments();
2955 type_arguments = type_arguments.Canonicalize(); 2955 type_arguments = type_arguments.Canonicalize();
2956 return Bind(new(Z) ConstantInstr(type_arguments)); 2956 return Bind(new(Z) ConstantInstr(type_arguments));
2957 } 2957 }
2958 Function& outer_function = Function::Handle(Z, owner()->function().raw()); 2958 Function& outer_function = Function::Handle(Z, owner()->function().raw());
2959 while (outer_function.IsLocalFunction()) { 2959 while (outer_function.IsLocalFunction()) {
2960 outer_function = outer_function.parent_function(); 2960 outer_function = outer_function.parent_function();
2961 } 2961 }
2962 if (outer_function.IsFactory()) { 2962 if (outer_function.IsFactory()) {
2963 // No instantiator for factories. 2963 // No instantiator for factories.
2964 ASSERT(instantiator == NULL); 2964 ASSERT(instantiator == NULL);
2965 LocalVariable* instantiator_var = 2965 LocalVariable* instantiator_var =
2966 owner()->parsed_function().instantiator(); 2966 owner()->parsed_function().instantiator();
2967 ASSERT(instantiator_var != NULL); 2967 ASSERT(instantiator_var != NULL);
2968 return Bind(BuildLoadLocal(*instantiator_var, token_pos)); 2968 return Bind(BuildLoadLocal(*instantiator_var, token_pos));
2969 } 2969 }
2970 if (instantiator == NULL) { 2970 if (instantiator == NULL) {
2971 instantiator = BuildInstantiator(token_pos, instantiator_class); 2971 instantiator = BuildInstantiator(token_pos);
2972 } 2972 }
2973 // The instantiator is the receiver of the caller, which is not a factory. 2973 // The instantiator is the receiver of the caller, which is not a factory.
2974 // The receiver cannot be null; extract its TypeArguments object. 2974 // The receiver cannot be null; extract its TypeArguments object.
2975 // Note that in the factory case, the instantiator is the first parameter 2975 // Note that in the factory case, the instantiator is the first parameter
2976 // of the factory, i.e. already a TypeArguments object. 2976 // of the factory, i.e. already a TypeArguments object.
2977 intptr_t type_arguments_field_offset = 2977 intptr_t type_arguments_field_offset =
2978 instantiator_class.type_arguments_field_offset(); 2978 instantiator_class.type_arguments_field_offset();
2979 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); 2979 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments);
2980 2980
2981 return Bind(new(Z) LoadFieldInstr( 2981 return Bind(new(Z) LoadFieldInstr(
(...skipping 1684 matching lines...) Expand 10 before | Expand all | Expand 10 after
4666 Script::Handle(function.script()), 4666 Script::Handle(function.script()),
4667 function.token_pos(), 4667 function.token_pos(),
4668 Report::AtLocation, 4668 Report::AtLocation,
4669 "FlowGraphBuilder Bailout: %s %s", 4669 "FlowGraphBuilder Bailout: %s %s",
4670 String::Handle(function.name()).ToCString(), 4670 String::Handle(function.name()).ToCString(),
4671 reason); 4671 reason);
4672 UNREACHABLE(); 4672 UNREACHABLE();
4673 } 4673 }
4674 4674
4675 } // namespace dart 4675 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698