From: Luca Bruno Date: Sun, 9 Jan 2011 17:20:13 +0000 (+0100) Subject: Support reference transfer for delegates X-Git-Tag: 0.11.4~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cc8693d42c4870100522b34fa22c0bf35ec3b12e;p=thirdparty%2Fvala.git Support reference transfer for delegates Fixes bug 632411. --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index ba0cac133..2808d09c2 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -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); } } } diff --git a/vala/valareferencetransferexpression.vala b/vala/valareferencetransferexpression.vala index 5e34282c3..2d82ac060 100644 --- a/vala/valareferencetransferexpression.vala +++ b/vala/valareferencetransferexpression.vala @@ -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;