[vala] codegen: Handle delegate_target attribute of fields



commit 0efcee2892c805d15fe46d4c9197669a0c51ad5f
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Wed May 30 17:02:42 2018 +0200

    codegen: Handle delegate_target attribute of fields
    
    Delegate fields without a delegate target don't require special handling
    on copy/destroy.
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/520

 codegen/valaccodeassignmentmodule.vala |  2 +-
 codegen/valaccodebasemodule.vala       | 12 +++++------
 codegen/valaccodestructmodule.vala     |  4 ++--
 codegen/valagtypemodule.vala           |  4 ++--
 tests/Makefile.am                      |  1 +
 tests/delegates/fields-no-target.vala  | 39 ++++++++++++++++++++++++++++++++++
 vala/valastruct.vala                   |  1 +
 7 files changed, 52 insertions(+), 11 deletions(-)
---
diff --git a/codegen/valaccodeassignmentmodule.vala b/codegen/valaccodeassignmentmodule.vala
index 6e9ce0dd1..c8f24383e 100644
--- a/codegen/valaccodeassignmentmodule.vala
+++ b/codegen/valaccodeassignmentmodule.vala
@@ -221,7 +221,7 @@ public class Vala.CCodeAssignmentModule : CCodeMemberAccessModule {
                if (lvalue.actual_value_type != null) {
                        type = lvalue.actual_value_type;
                }
-               if (requires_destroy (type)) {
+               if (get_ccode_delegate_target (field) && requires_destroy (type)) {
                        /* unref old value */
                        ccode.add_expression (destroy_field (field, instance));
                }
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 4c1e60685..9147a5fa0 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1084,7 +1084,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                        decl_space.add_type_member_declaration (cdecl);
                                }
                        }
-               } else if (f.variable_type is DelegateType) {
+               } else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
                        var delegate_type = (DelegateType) f.variable_type;
                        if (delegate_type.delegate_symbol.has_target) {
                                // create field to store delegate target
@@ -1172,7 +1172,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                                        var rhs_array_len = get_array_length_cvalue 
(field_value, 1);
                                                        ccode.add_assignment (lhs_array_size, rhs_array_len);
                                                }
-                                       } else if (f.variable_type is DelegateType) {
+                                       } else if (f.variable_type is DelegateType && 
get_ccode_delegate_target (f)) {
                                                var delegate_type = (DelegateType) f.variable_type;
                                                if (delegate_type.delegate_symbol.has_target) {
                                                        var field_value = get_field_cvalue (f, 
load_this_parameter ((TypeSymbol) f.parent_symbol));
@@ -1194,7 +1194,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                pop_context ();
                        }
 
-                       if (requires_destroy (f.variable_type) && instance_finalize_context != null) {
+                       if (get_ccode_delegate_target (f) && requires_destroy (f.variable_type) && 
instance_finalize_context != null) {
                                push_context (instance_finalize_context);
                                ccode.add_expression (destroy_field (f, load_this_parameter ((TypeSymbol) 
f.parent_symbol)));
                                pop_context ();
@@ -1304,7 +1304,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                                        cfile.add_type_member_declaration (cdecl);
                                                }
                                        }
-                               } else if (f.variable_type is DelegateType) {
+                               } else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
                                        var delegate_type = (DelegateType) f.variable_type;
                                        if (delegate_type.delegate_symbol.has_target) {
                                                // create field to store delegate target
@@ -6376,7 +6376,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                var this_value = load_this_parameter (st);
                foreach (Field f in st.get_fields ()) {
                        if (f.binding == MemberBinding.INSTANCE) {
-                               if (requires_destroy (f.variable_type)) {
+                               if (get_ccode_delegate_target (f) && requires_destroy (f.variable_type)) {
                                        ccode.add_expression (destroy_field (f, this_value));
                                }
                        }
@@ -6407,7 +6407,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                foreach (Field f in st.get_fields ()) {
                        if (f.binding == MemberBinding.INSTANCE) {
                                var value = load_field (f, load_this_parameter ((TypeSymbol) st));
-                               if (requires_copy (f.variable_type))  {
+                               if (get_ccode_delegate_target (f) && requires_copy (f.variable_type))  {
                                        value = copy_value (value, f);
                                        if (value == null) {
                                                // error case, continue to avoid critical
diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala
index 7b20f504a..d9237e656 100644
--- a/codegen/valaccodestructmodule.vala
+++ b/codegen/valaccodestructmodule.vala
@@ -95,7 +95,7 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
                                                        instance_struct.add_field (get_ccode_name (len_type), 
get_array_size_cname (get_ccode_name (f)));
                                                }
                                        }
-                               } else if (f.variable_type is DelegateType) {
+                               } else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
                                        var delegate_type = (DelegateType) f.variable_type;
                                        if (delegate_type.delegate_symbol.has_target) {
                                                // create field to store delegate target
@@ -301,7 +301,7 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
                foreach (var f in st.get_fields ()) {
                        if (f.binding == MemberBinding.INSTANCE) {
                                var value = load_field (f, load_this_parameter ((TypeSymbol) st));
-                               if (requires_copy (f.variable_type))  {
+                               if (get_ccode_delegate_target (f) && requires_copy (f.variable_type))  {
                                        value = copy_value (value, f);
                                        if (value == null) {
                                                // error case, continue to avoid critical
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index abb19f664..3d977784d 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -413,7 +413,7 @@ public class Vala.GTypeModule : GErrorModule {
                                                instance_struct.add_field (get_ccode_name (len_type), 
get_array_size_cname (get_ccode_name (f)));
                                        }
                                }
-                       } else if (f.variable_type is DelegateType) {
+                       } else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
                                var delegate_type = (DelegateType) f.variable_type;
                                if (delegate_type.delegate_symbol.has_target) {
                                        // create field to store delegate target
@@ -514,7 +514,7 @@ public class Vala.GTypeModule : GErrorModule {
                                                                instance_priv_struct.add_field 
(get_ccode_name (len_type), get_array_size_cname (get_ccode_name (f)));
                                                        }
                                                }
-                                       } else if (f.variable_type is DelegateType) {
+                                       } else if (f.variable_type is DelegateType && 
get_ccode_delegate_target (f)) {
                                                var delegate_type = (DelegateType) f.variable_type;
                                                if (delegate_type.delegate_symbol.has_target) {
                                                        // create field to store delegate target
diff --git a/tests/Makefile.am b/tests/Makefile.am
index aec6e33f2..c05a68d51 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -208,6 +208,7 @@ TESTS = \
        delegates/delegates.vala \
        delegates/delegates-error.test \
        delegates/fields.vala \
+       delegates/fields-no-target.vala \
        delegates/reference_transfer.vala \
        delegates/wrapper.vala \
        delegates/bug519949.test \
diff --git a/tests/delegates/fields-no-target.vala b/tests/delegates/fields-no-target.vala
new file mode 100644
index 000000000..ad328deeb
--- /dev/null
+++ b/tests/delegates/fields-no-target.vala
@@ -0,0 +1,39 @@
+public delegate void FooFunc ();
+
+[CCode (delegate_target = false)]
+public FooFunc func;
+
+public struct Foo {
+       [CCode (delegate_target = false)]
+       public FooFunc func;
+       public int i;
+}
+
+public class Bar {
+       [CCode (delegate_target = false)]
+       public FooFunc func;
+       public int i;
+}
+
+void foo_cb () {
+}
+
+const Foo[] foos = {
+       { foo_cb, 42 }
+};
+
+void main() {
+       func = foo_cb;
+
+       Foo f_stack = { foo_cb, 23 };
+       Foo? f_heap = { foo_cb, 4711 };
+
+       assert (f_stack.i == 23);
+       assert (f_heap.i == 4711);
+       assert (foos[0].i == 42);
+
+       Bar b = new Bar ();
+       b.func = foo_cb;
+       b.i = 42;
+}
+
diff --git a/vala/valastruct.vala b/vala/valastruct.vala
index bca78510a..1c4ba768c 100644
--- a/vala/valastruct.vala
+++ b/vala/valastruct.vala
@@ -449,6 +449,7 @@ public class Vala.Struct : TypeSymbol {
 
                foreach (Field f in fields) {
                        if (f.binding == MemberBinding.INSTANCE
+                           && f.get_attribute_bool ("CCode", "delegate_target", true)
                            && f.variable_type.is_disposable ()) {
                                return true;
                        }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]