summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJürg Billeter <j@bitron.ch>2009-09-18 12:49:34 +0200
committerJürg Billeter <j@bitron.ch>2009-09-18 12:49:34 +0200
commitf3f62d0591f6b77851b3a243e867f1df91cb899b (patch)
tree4abb20f44484ad77750d5e014d406e1e0951a552
parent2e831744dcaac0d76f7ff89bfd13a1ba5dd951d7 (diff)
downloadvala-f3f62d0591f6b77851b3a243e867f1df91cb899b.tar.gz
Fix methods returning owned delegates
-rw-r--r--codegen/valaccodeassignmentmodule.vala8
-rw-r--r--codegen/valaccodebasemodule.vala51
-rw-r--r--codegen/valaccodedelegatemodule.vala58
-rw-r--r--codegen/valaccodemethodcallmodule.vala62
-rw-r--r--codegen/valaccodemethodmodule.vala7
-rw-r--r--codegen/valagsignalmodule.vala13
-rw-r--r--vala/valadelegatetype.vala13
-rw-r--r--vala/valaexpression.vala3
-rw-r--r--vala/valalambdaexpression.vala1
9 files changed, 146 insertions, 70 deletions
diff --git a/codegen/valaccodeassignmentmodule.vala b/codegen/valaccodeassignmentmodule.vala
index 371e8c168..9ae2690f5 100644
--- a/codegen/valaccodeassignmentmodule.vala
+++ b/codegen/valaccodeassignmentmodule.vala
@@ -165,9 +165,13 @@ internal class Vala.CCodeAssignmentModule : CCodeMemberAccessModule {
}
}
} else if (instance_delegate) {
- var lhs_delegate_target = get_delegate_target_cexpression (assignment.left);
- var rhs_delegate_target = get_delegate_target_cexpression (assignment.right);
+ CCodeExpression lhs_delegate_target_destroy_notify, rhs_delegate_target_destroy_notify;
+ var lhs_delegate_target = get_delegate_target_cexpression (assignment.left, out lhs_delegate_target_destroy_notify);
+ var rhs_delegate_target = get_delegate_target_cexpression (assignment.right, out rhs_delegate_target_destroy_notify);
ccomma.append_expression (new CCodeAssignment (lhs_delegate_target, rhs_delegate_target));
+ if (assignment.right.target_type.value_owned) {
+ ccomma.append_expression (new CCodeAssignment (lhs_delegate_target_destroy_notify, rhs_delegate_target_destroy_notify));
+ }
}
ccomma.append_expression (get_variable_cexpression (temp_decl.name));
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 051651aeb..1b686c468 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1648,6 +1648,9 @@ internal class Vala.CCodeBaseModule : CCodeModule {
}
} else if (local.variable_type is DelegateType) {
data.add_field ("gpointer", get_delegate_target_cname (get_variable_cname (local.name)));
+ if (local.variable_type.value_owned) {
+ data.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
+ }
}
if (requires_destroy (local.variable_type)) {
@@ -1721,6 +1724,10 @@ internal class Vala.CCodeBaseModule : CCodeModule {
} else if (param.parameter_type is DelegateType) {
data.add_field ("gpointer", get_delegate_target_cname (get_variable_cname (param.name)));
cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name))))));
+ if (param.parameter_type.value_owned) {
+ data.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
+ cblock.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (block_id)), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))), new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name))))));
+ }
}
if (requires_destroy (param_type)) {
@@ -1889,6 +1896,10 @@ internal class Vala.CCodeBaseModule : CCodeModule {
// create variable to store delegate target
var target_var = new LocalVariable (new PointerType (new VoidType ()), get_delegate_target_cname (get_variable_cname (local.name)));
temp_vars.insert (0, target_var);
+ if (deleg_type.value_owned) {
+ var target_destroy_notify_var = new LocalVariable (new DelegateType ((Delegate) context.root.scope.lookup ("GLib").scope.lookup ("DestroyNotify")), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
+ temp_vars.insert (0, target_destroy_notify_var);
+ }
}
}
@@ -1938,11 +1949,21 @@ internal class Vala.CCodeBaseModule : CCodeModule {
var block = (Block) local.parent_symbol;
lhs_delegate_target = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (local.name));
}
- var rhs_delegate_target = get_delegate_target_cexpression (local.initializer);
+ CCodeExpression rhs_delegate_target_destroy_notify;
+ var rhs_delegate_target = get_delegate_target_cexpression (local.initializer, out rhs_delegate_target_destroy_notify);
ccomma.append_expression (new CCodeAssignment (lhs_delegate_target, rhs_delegate_target));
-
+
+ if (deleg_type.value_owned) {
+ var lhs_delegate_target_destroy_notify = get_variable_cexpression (get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
+ if (local.captured) {
+ var block = (Block) local.parent_symbol;
+ lhs_delegate_target = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_destroy_notify_cname (local.name));
+ }
+ ccomma.append_expression (new CCodeAssignment (lhs_delegate_target_destroy_notify, rhs_delegate_target_destroy_notify));
+ }
+
ccomma.append_expression (get_variable_cexpression (temp_var.name));
-
+
rhs = ccomma;
}
}
@@ -2831,8 +2852,16 @@ internal class Vala.CCodeBaseModule : CCodeModule {
if (current_method == null || !current_method.coroutine) {
target_l = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, target_l);
}
- var target_r = get_delegate_target_cexpression (stmt.return_expression);
+ CCodeExpression target_r_destroy_notify;
+ var target_r = get_delegate_target_cexpression (stmt.return_expression, out target_r_destroy_notify);
ccomma.append_expression (new CCodeAssignment (target_l, target_r));
+ if (delegate_type.value_owned) {
+ var target_l_destroy_notify = get_result_cexpression (get_delegate_target_destroy_notify_cname ("result"));
+ if (current_method == null || !current_method.coroutine) {
+ target_l_destroy_notify = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, target_l_destroy_notify);
+ }
+ ccomma.append_expression (new CCodeAssignment (target_l_destroy_notify, target_r_destroy_notify));
+ }
ccomma.append_expression (get_variable_cexpression (return_expr_decl.name));
@@ -3011,7 +3040,7 @@ internal class Vala.CCodeBaseModule : CCodeModule {
assert_not_reached ();
}
- public virtual CCodeExpression get_delegate_target_cexpression (Expression delegate_expr) {
+ public virtual CCodeExpression get_delegate_target_cexpression (Expression delegate_expr, out CCodeExpression delegate_target_destroy_notify) {
assert_not_reached ();
}
@@ -3511,8 +3540,12 @@ internal class Vala.CCodeBaseModule : CCodeModule {
var deleg_type = (DelegateType) param.parameter_type;
var d = deleg_type.delegate_symbol;
if (d.has_target) {
- var delegate_target = get_delegate_target_cexpression (arg);
+ CCodeExpression delegate_target_destroy_notify;
+ var delegate_target = get_delegate_target_cexpression (arg, out delegate_target_destroy_notify);
carg_map.set (get_param_pos (param.cdelegate_target_parameter_position), delegate_target);
+ if (deleg_type.value_owned) {
+ carg_map.set (get_param_pos (param.cdelegate_target_parameter_position + 0.01), delegate_target_destroy_notify);
+ }
}
}
@@ -3658,7 +3691,8 @@ internal class Vala.CCodeBaseModule : CCodeModule {
} else {
lhs = new CCodeMemberAccess.pointer (typed_inst, get_delegate_target_cname (f.get_cname ()));
}
- var rhs_delegate_target = get_delegate_target_cexpression (init.initializer);
+ CCodeExpression rhs_delegate_target_destroy_notify;
+ var rhs_delegate_target = get_delegate_target_cexpression (init.initializer, out rhs_delegate_target_destroy_notify);
ccomma.append_expression (new CCodeAssignment (lhs, rhs_delegate_target));
}
} else if (init.symbol_reference is Property) {
@@ -4316,7 +4350,8 @@ internal class Vala.CCodeBaseModule : CCodeModule {
} else if (prop.property_type is DelegateType && rhs != null) {
var delegate_type = (DelegateType) prop.property_type;
if (delegate_type.delegate_symbol.has_target) {
- ccall.add_argument (get_delegate_target_cexpression (rhs));
+ CCodeExpression delegate_target_destroy_notify;
+ ccall.add_argument (get_delegate_target_cexpression (rhs, out delegate_target_destroy_notify));
}
}
diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala
index 182cf5a01..85d9ea9ee 100644
--- a/codegen/valaccodedelegatemodule.vala
+++ b/codegen/valaccodedelegatemodule.vala
@@ -123,9 +123,11 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
return "%s_target".printf (delegate_cname);
}
- public override CCodeExpression get_delegate_target_cexpression (Expression delegate_expr) {
+ public override CCodeExpression get_delegate_target_cexpression (Expression delegate_expr, out CCodeExpression delegate_target_destroy_notify) {
bool is_out = false;
+ delegate_target_destroy_notify = new CCodeConstant ("NULL");
+
if (delegate_expr is UnaryExpression) {
var unary_expr = (UnaryExpression) delegate_expr;
if (unary_expr.operator == UnaryOperator.OUT || unary_expr.operator == UnaryOperator.REF) {
@@ -136,6 +138,9 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
if (delegate_expr is MethodCall) {
var invocation_expr = (MethodCall) delegate_expr;
+ if (invocation_expr.delegate_target_destroy_notify != null) {
+ delegate_target_destroy_notify = invocation_expr.delegate_target_destroy_notify;
+ }
return invocation_expr.delegate_target;
} else if (delegate_expr is LambdaExpression) {
var closure_block = current_symbol as Block;
@@ -143,9 +148,32 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
closure_block = closure_block.parent_symbol as Block;
}
if (closure_block != null) {
- return get_variable_cexpression ("_data%d_".printf (get_block_id (closure_block)));
+ int block_id = get_block_id (closure_block);
+ var delegate_target = get_variable_cexpression ("_data%d_".printf (block_id));
+ if (delegate_expr.value_type.value_owned) {
+ var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_ref".printf (block_id)));
+ ref_call.add_argument (delegate_target);
+ delegate_target = ref_call;
+ delegate_target_destroy_notify = new CCodeIdentifier ("block%d_data_unref".printf (block_id));
+ }
+ return delegate_target;
} else if (get_this_type () != null || in_constructor) {
- return new CCodeIdentifier ("self");
+ CCodeExpression delegate_target = new CCodeIdentifier ("self");
+ if (delegate_expr.value_type.value_owned) {
+ if (get_this_type () != null) {
+ var ref_call = new CCodeFunctionCall (get_dup_func_expression (get_this_type (), delegate_expr.source_reference));
+ ref_call.add_argument (delegate_target);
+ delegate_target = ref_call;
+ delegate_target_destroy_notify = get_destroy_func_expression (get_this_type ());
+ } else {
+ // in constructor
+ var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("g_object_ref"));
+ ref_call.add_argument (delegate_target);
+ delegate_target = ref_call;
+ delegate_target_destroy_notify = new CCodeIdentifier ("g_object_unref");
+ }
+ }
+ return delegate_target;
} else {
return new CCodeConstant ("NULL");
}
@@ -155,17 +183,22 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
if (param.captured) {
// captured variables are stored on the heap
var block = ((Method) param.parent_symbol).body;
+ delegate_target_destroy_notify = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_variable_cname (param.name)));
} else if (current_method != null && current_method.coroutine) {
+ delegate_target_destroy_notify = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (param.name)));
} else {
CCodeExpression target_expr = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (param.name)));
+ delegate_target_destroy_notify = new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
if (param.direction != ParameterDirection.IN) {
// accessing argument of out/ref param
target_expr = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, target_expr);
+ delegate_target_destroy_notify = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, delegate_target_destroy_notify);
}
if (is_out) {
- // passing array as out/ref
+ // passing delegate as out/ref
+ delegate_target_destroy_notify = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, delegate_target_destroy_notify);
return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, target_expr);
} else {
return target_expr;
@@ -176,12 +209,16 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
if (local.captured) {
// captured variables are stored on the heap
var block = (Block) local.parent_symbol;
+ delegate_target_destroy_notify = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
return new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_variable_cname (local.name)));
} else if (current_method != null && current_method.coroutine) {
+ delegate_target_destroy_notify = new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
return new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), get_delegate_target_cname (get_variable_cname (local.name)));
} else {
var target_expr = new CCodeIdentifier (get_delegate_target_cname (get_variable_cname (local.name)));
+ delegate_target_destroy_notify = new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_variable_cname (local.name)));
if (is_out) {
+ delegate_target_destroy_notify = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, delegate_target_destroy_notify);
return new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, target_expr);
} else {
return target_expr;
@@ -230,7 +267,14 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
} else if (m.is_async_callback) {
return new CCodeIdentifier ("data");
} else {
- return (CCodeExpression) get_ccodenode (ma.inner);
+ var delegate_target = (CCodeExpression) get_ccodenode (ma.inner);
+ if (ma.inner.value_type.data_type != null && ma.inner.value_type.data_type.is_reference_counting ()) {
+ var ref_call = new CCodeFunctionCall (get_dup_func_expression (ma.inner.value_type, delegate_expr.source_reference));
+ ref_call.add_argument (delegate_target);
+ delegate_target = ref_call;
+ delegate_target_destroy_notify = get_destroy_func_expression (ma.inner.value_type);
+ }
+ return delegate_target;
}
} else if (delegate_expr.symbol_reference is Property) {
return delegate_expr.delegate_target;
@@ -471,6 +515,7 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
string ctypename = param.parameter_type.get_cname ();
string target_ctypename = "void*";
+ string target_destroy_notify_ctypename = "GDestroyNotify";
if (param.parent_symbol is Delegate
&& param.parameter_type.get_cname () == ((Delegate) param.parent_symbol).get_cname ()) {
@@ -481,6 +526,7 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
if (param.direction != ParameterDirection.IN) {
ctypename += "*";
target_ctypename += "*";
+ target_destroy_notify_ctypename += "*";
}
param.ccodenode = new CCodeFormalParameter (get_variable_cname (param.name), ctypename);
@@ -503,7 +549,7 @@ internal class Vala.CCodeDelegateModule : CCodeArrayModule {
carg_map.set (get_param_pos (param.cdelegate_target_parameter_position), get_variable_cexpression (cparam.name));
}
if (deleg_type.value_owned) {
- cparam = new CCodeFormalParameter (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)), "GDestroyNotify");
+ cparam = new CCodeFormalParameter (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)), target_destroy_notify_ctypename);
cparam_map.set (get_param_pos (param.cdelegate_target_parameter_position + 0.01), cparam);
if (carg_map != null) {
carg_map.set (get_param_pos (param.cdelegate_target_parameter_position + 0.01), get_variable_cexpression (cparam.name));
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index c47c4bc53..31d145e86 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -289,50 +289,18 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var deleg_type = (DelegateType) param.parameter_type;
var d = deleg_type.delegate_symbol;
if (d.has_target) {
- var delegate_target = get_delegate_target_cexpression (arg);
+ CCodeExpression delegate_target_destroy_notify;
+ var delegate_target = get_delegate_target_cexpression (arg, out delegate_target_destroy_notify);
+ carg_map.set (get_param_pos (param.cdelegate_target_parameter_position), delegate_target);
if (deleg_type.value_owned) {
- CCodeExpression delegate_target_destroy_notify;
- var delegate_method = arg.symbol_reference as Method;
- var lambda = arg as LambdaExpression;
- var arg_ma = arg as MemberAccess;
- if (lambda != null) {
- if (delegate_method.closure) {
- var closure_block = current_symbol as Block;
- while (closure_block != null && !closure_block.captured) {
- closure_block = closure_block.parent_symbol as Block;
- }
- int block_id = get_block_id (closure_block);
- var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_ref".printf (block_id)));
- ref_call.add_argument (delegate_target);
- delegate_target = ref_call;
- delegate_target_destroy_notify = new CCodeIdentifier ("block%d_data_unref".printf (block_id));
- } else if (get_this_type () != null) {
- // type of delegate target is same as `this'
- // for lambda expressions in instance methods
- var ref_call = new CCodeFunctionCall (get_dup_func_expression (get_this_type (), arg.source_reference));
- ref_call.add_argument (delegate_target);
- delegate_target = ref_call;
- delegate_target_destroy_notify = get_destroy_func_expression (get_this_type ());
- } else {
- delegate_target_destroy_notify = new CCodeConstant ("NULL");
- }
- } else if (delegate_method != null && delegate_method.binding == MemberBinding.INSTANCE
- && arg_ma != null && arg_ma.inner != null && arg_ma.inner.value_type.data_type != null
- && arg_ma.inner.value_type.data_type.is_reference_counting ()) {
- var ref_call = new CCodeFunctionCall (get_dup_func_expression (arg_ma.inner.value_type, arg.source_reference));
- ref_call.add_argument (delegate_target);
- delegate_target = ref_call;
- delegate_target_destroy_notify = get_destroy_func_expression (arg_ma.inner.value_type);
- } else {
- delegate_target_destroy_notify = new CCodeConstant ("NULL");
- }
carg_map.set (get_param_pos (param.cdelegate_target_parameter_position + 0.01), delegate_target_destroy_notify);
- }
- carg_map.set (get_param_pos (param.cdelegate_target_parameter_position), delegate_target);
+ }
multiple_cargs = true;
}
} else if (param.parameter_type is MethodType) {
- carg_map.set (get_param_pos (param.cdelegate_target_parameter_position), get_delegate_target_cexpression (arg));
+ // callbacks in dynamic method calls
+ CCodeExpression delegate_target_destroy_notify;
+ carg_map.set (get_param_pos (param.cdelegate_target_parameter_position), get_delegate_target_cexpression (arg, out delegate_target_destroy_notify));
multiple_cargs = true;
}
@@ -485,6 +453,17 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
out_arg_map.set (get_param_pos (m.cdelegate_target_parameter_position), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
expr.delegate_target = temp_ref;
+
+ if (deleg_type.value_owned) {
+ temp_var = get_temp_variable (new DelegateType ((Delegate) context.root.scope.lookup ("GLib").scope.lookup ("DestroyNotify")));
+ temp_ref = get_variable_cexpression (temp_var.name);
+
+ temp_vars.insert (0, temp_var);
+
+ out_arg_map.set (get_param_pos (m.cdelegate_target_parameter_position + 0.01), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, temp_ref));
+
+ expr.delegate_target_destroy_notify = temp_ref;
+ }
}
}
@@ -562,8 +541,9 @@ internal class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
var deleg_type = (DelegateType) itype;
var d = deleg_type.delegate_symbol;
if (d.has_target) {
- in_arg_map.set (get_param_pos (d.cinstance_parameter_position), get_delegate_target_cexpression (expr.call));
- out_arg_map.set (get_param_pos (d.cinstance_parameter_position), get_delegate_target_cexpression (expr.call));
+ CCodeExpression delegate_target_destroy_notify;
+ in_arg_map.set (get_param_pos (d.cinstance_parameter_position), get_delegate_target_cexpression (expr.call, out delegate_target_destroy_notify));
+ out_arg_map.set (get_param_pos (d.cinstance_parameter_position), get_delegate_target_cexpression (expr.call, out delegate_target_destroy_notify));
}
}
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 0a846b665..363c6c435 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -111,6 +111,13 @@ internal class Vala.CCodeMethodModule : CCodeStructModule {
if (carg_map != null) {
carg_map.set (get_param_pos (m.cdelegate_target_parameter_position), get_variable_cexpression (cparam.name));
}
+ if (deleg_type.value_owned) {
+ cparam = new CCodeFormalParameter (get_delegate_target_destroy_notify_cname ("result"), "GDestroyNotify*");
+ cparam_map.set (get_param_pos (m.cdelegate_target_parameter_position + 0.01), cparam);
+ if (carg_map != null) {
+ carg_map.set (get_param_pos (m.cdelegate_target_parameter_position + 0.01), get_variable_cexpression (cparam.name));
+ }
+ }
}
}
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index 64b447faf..2387b127a 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -652,19 +652,12 @@ internal class Vala.GSignalModule : GObjectModule {
if (m.closure) {
// g_signal_connect_data
- var closure_block = current_symbol as Block;
- while (closure_block != null && !closure_block.captured) {
- closure_block = closure_block.parent_symbol as Block;
- }
- int block_id = get_block_id (closure_block);
-
// fourth argument: user_data
- var ref_call = new CCodeFunctionCall (new CCodeIdentifier ("block%d_data_ref".printf (block_id)));
- ref_call.add_argument (get_delegate_target_cexpression (handler));
- ccall.add_argument (new CCodeCastExpression (ref_call, "GCallback"));
+ CCodeExpression handler_destroy_notify;
+ ccall.add_argument (get_delegate_target_cexpression (handler, out handler_destroy_notify));
// fifth argument: destroy_notify
- ccall.add_argument (new CCodeCastExpression (new CCodeIdentifier ("block%d_data_unref".printf (block_id)), "GClosureNotify"));
+ ccall.add_argument (new CCodeCastExpression (handler_destroy_notify, "GClosureNotify"));
// sixth argument: connect_flags
ccall.add_argument (new CCodeConstant ("0"));
diff --git a/vala/valadelegatetype.vala b/vala/valadelegatetype.vala
index 40035d9f7..1f32a7e5d 100644
--- a/vala/valadelegatetype.vala
+++ b/vala/valadelegatetype.vala
@@ -1,6 +1,6 @@
/* valadelegatetype.vala
*
- * Copyright (C) 2007-2008 Jürg Billeter
+ * Copyright (C) 2007-2009 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -54,7 +54,16 @@ public class Vala.DelegateType : DataType {
}
public override DataType copy () {
- return new DelegateType (delegate_symbol);
+ var result = new DelegateType (delegate_symbol);
+ result.source_reference = source_reference;
+ result.value_owned = value_owned;
+ result.nullable = nullable;
+
+ foreach (DataType arg in get_type_arguments ()) {
+ result.add_type_argument (arg.copy ());
+ }
+
+ return result;
}
public override string? get_cname () {
diff --git a/vala/valaexpression.vala b/vala/valaexpression.vala
index 431349972..a97ed102e 100644
--- a/vala/valaexpression.vala
+++ b/vala/valaexpression.vala
@@ -66,7 +66,8 @@ public abstract class Vala.Expression : CodeNode {
private Gee.List<CCodeExpression> array_sizes = new ArrayList<CCodeExpression> ();
- public CCodeExpression delegate_target { get; set; }
+ public CCodeExpression? delegate_target { get; set; }
+ public CCodeExpression? delegate_target_destroy_notify { get; set; }
/**
* Returns whether this expression is constant, i.e. whether this
diff --git a/vala/valalambdaexpression.vala b/vala/valalambdaexpression.vala
index 16a51c1c3..c9794c2ad 100644
--- a/vala/valalambdaexpression.vala
+++ b/vala/valalambdaexpression.vala
@@ -223,6 +223,7 @@ public class Vala.LambdaExpression : Expression {
}
value_type = new MethodType (method);
+ value_type.value_owned = target_type.value_owned;
return !error;
}