]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Support reference transfer for delegates
authorLuca Bruno <lucabru@src.gnome.org>
Sun, 9 Jan 2011 17:20:13 +0000 (18:20 +0100)
committerJürg Billeter <j@bitron.ch>
Sat, 15 Jan 2011 09:19:20 +0000 (10:19 +0100)
Fixes bug 632411.

codegen/valaccodebasemodule.vala
vala/valareferencetransferexpression.vala

index ba0cac133bca0a0a83b19efcbbeffbec2f9a589a..2808d09c2f0c85c1351734cf3a3d4613d339a479 100644 (file)
@@ -274,6 +274,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
        public TypeSymbol gbytearray_type;
        public TypeSymbol gptrarray_type;
        public TypeSymbol gthreadpool_type;
+       public DataType gdestroynotify_type;
        public DataType gquark_type;
        public Struct gvalue_type;
        public Class gvariant_type;
@@ -412,6 +413,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        gbytearray_type = (TypeSymbol) glib_ns.scope.lookup ("ByteArray");
                        gptrarray_type = (TypeSymbol) glib_ns.scope.lookup ("PtrArray");
                        gthreadpool_type = (TypeSymbol) glib_ns.scope.lookup ("ThreadPool");
+                       gdestroynotify_type = new DelegateType ((Delegate) glib_ns.scope.lookup ("DestroyNotify"));
 
                        gquark_type = new IntegerType ((Struct) glib_ns.scope.lookup ("Quark"));
                        gvalue_type = (Struct) glib_ns.scope.lookup ("Value");
@@ -4731,7 +4733,9 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                var cvar = get_variable_cexpression (temp_decl.name);
 
                ccode.add_expression (new CCodeAssignment (cvar, get_cvalue (expr.inner)));
-               ccode.add_expression (new CCodeAssignment (get_cvalue (expr.inner), new CCodeConstant ("NULL")));
+               if (!(expr.value_type is DelegateType)) {
+                       ccode.add_expression (new CCodeAssignment (get_cvalue (expr.inner), new CCodeConstant ("NULL")));
+               }
 
                set_cvalue (expr, cvar);
 
@@ -4744,10 +4748,20 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
 
                var delegate_type = expr.value_type as DelegateType;
                if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
+                       var temp_target_decl = get_temp_variable (new PointerType (new VoidType ()), true, expr, false);
+                       emit_temp_var (temp_target_decl);
+                       var target_cvar = get_variable_cexpression (temp_target_decl.name);
                        CCodeExpression target_destroy_notify;
-                       set_delegate_target (expr, get_delegate_target_cexpression (expr.inner, out target_destroy_notify));
+                       var target = get_delegate_target_cexpression (expr.inner, out target_destroy_notify);
+                       ccode.add_expression (new CCodeAssignment (target_cvar, target));
+                       set_delegate_target (expr, target_cvar);
                        if (target_destroy_notify != null) {
-                               set_delegate_target_destroy_notify (expr, target_destroy_notify);
+                               var temp_target_destroy_notify_decl = get_temp_variable (gdestroynotify_type, true, expr, false);
+                               emit_temp_var (temp_target_destroy_notify_decl);
+                               var target_destroy_notify_cvar = get_variable_cexpression (temp_target_destroy_notify_decl.name);
+                               ccode.add_expression (new CCodeAssignment (target_destroy_notify_cvar, target_destroy_notify));
+                               ccode.add_expression (new CCodeAssignment (target_destroy_notify, new CCodeConstant ("NULL")));
+                               set_delegate_target_destroy_notify (expr, target_destroy_notify_cvar);
                        }
                }
        }
index 5e34282c3d782945013e2c5245e4cec00bc22ecd..2d82ac060b8f00e1c047b0e244461529d9b04d7c 100644 (file)
@@ -101,14 +101,6 @@ public class Vala.ReferenceTransferExpression : Expression {
                        return false;
                }
 
-               if (inner.value_type is DelegateType) {
-                       // would require fixing code generator to ensure _target_destroy_notify
-                       // is set to NULL as well after reference transfer, leads to double free otherwise
-                       error = true;
-                       Report.error (source_reference, "Reference transfer not supported for delegates");
-                       return false;
-               }
-
                value_type = inner.value_type.copy ();
                value_type.value_owned = true;