if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
if (get_delegate_target_cvalue (lvalue) != null) {
ccode.add_assignment (get_delegate_target_cvalue (lvalue), get_delegate_target_cvalue (value));
- if (get_delegate_target_destroy_notify_cvalue (lvalue) != null) {
- ccode.add_assignment (get_delegate_target_destroy_notify_cvalue (lvalue), get_delegate_target_destroy_notify_cvalue (value));
+ var lvalue_destroy_notify = get_delegate_target_destroy_notify_cvalue (lvalue);
+ var rvalue_destroy_notify = get_delegate_target_destroy_notify_cvalue (value);
+ if (lvalue_destroy_notify != null) {
+ if (rvalue_destroy_notify != null) {
+ ccode.add_assignment (lvalue_destroy_notify, rvalue_destroy_notify);
+ } else {
+ ccode.add_assignment (lvalue_destroy_notify, new CCodeConstant ("NULL"));
+ }
}
}
}
}
decl_space.add_type_member_declaration (cdecl);
- if (delegate_type.value_owned) {
+ if (delegate_type.value_owned && !delegate_type.is_called_once) {
cdecl = new CCodeDeclaration ("GDestroyNotify");
cdecl.add_declarator (new CCodeVariableDeclarator (get_delegate_target_destroy_notify_cname (get_ccode_name (f))));
if (f.is_private_symbol ()) {
}
cfile.add_type_member_declaration (target_def);
- if (delegate_type.value_owned) {
+ if (delegate_type.is_disposable ()) {
var target_destroy_notify_def = new CCodeDeclaration ("GDestroyNotify");
target_destroy_notify_def.add_declarator (new CCodeVariableDeclarator (get_delegate_target_destroy_notify_cname (get_ccode_name (f)), new CCodeConstant ("NULL")));
if (!f.is_private_symbol ()) {
}
} else if (deleg_type != null && deleg_type.delegate_symbol.has_target) {
data.add_field ("gpointer", get_ccode_delegate_target_name (param));
- if (param.variable_type.value_owned) {
+ if (param.variable_type.is_disposable ()) {
data.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
// reference transfer for delegates
var lvalue = get_parameter_cvalue (param);
if (!deleg_type.delegate_symbol.has_target) {
value.delegate_target_cvalue = new CCodeConstant ("NULL");
((GLibValue) value).lvalue = false;
- } else if (!deleg_type.value_owned) {
+ } else if (!deleg_type.is_disposable ()) {
value.delegate_target_destroy_notify_cvalue = new CCodeConstant ("NULL");
((GLibValue) value).lvalue = false;
}
if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
ccode.add_assignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (get_ccode_delegate_target_name (param))), get_delegate_target_cvalue (value));
- if (delegate_type.value_owned) {
+ if (delegate_type.is_disposable ()) {
ccode.add_assignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, get_variable_cexpression (get_delegate_target_destroy_notify_cname (param.name))), get_delegate_target_destroy_notify_cvalue (get_parameter_cvalue (param)));
}
}
}
var target_r = get_delegate_target_cvalue (temp_value);
ccode.add_assignment (target_l, target_r);
- if (delegate_type.value_owned) {
+ if (delegate_type.is_disposable ()) {
var target_l_destroy_notify = get_result_cexpression (get_delegate_target_destroy_notify_cname ("result"));
if (!is_in_coroutine ()) {
target_l_destroy_notify = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, target_l_destroy_notify);
CCodeExpression delegate_target_destroy_notify;
var delegate_target = get_delegate_target_cexpression (arg, out delegate_target_destroy_notify);
carg_map.set (get_param_pos (get_ccode_delegate_target_pos (param)), delegate_target);
- if (deleg_type.value_owned && !deleg_type.is_called_once) {
+ if (deleg_type.is_disposable ()) {
carg_map.set (get_param_pos (get_ccode_delegate_target_pos (param) + 0.01), delegate_target_destroy_notify);
}
}
if (param_d.has_target) {
cparam = new CCodeParameter (get_delegate_target_cname (get_variable_cname (param.name)), "void*");
cfundecl.add_parameter (cparam);
- if (deleg_type.value_owned) {
+ if (deleg_type.is_disposable ()) {
cparam = new CCodeParameter (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)), "GDestroyNotify*");
cfundecl.add_parameter (cparam);
}
if (result_d.has_target) {
var cparam = new CCodeParameter (get_delegate_target_cname ("result"), "void**");
cfundecl.add_parameter (cparam);
- if (deleg_type.value_owned) {
+ if (deleg_type.is_disposable ()) {
cparam = new CCodeParameter (get_delegate_target_destroy_notify_cname ("result"), "GDestroyNotify*");
cfundecl.add_parameter (cparam);
}
if (deleg_type.delegate_symbol.has_target) {
var cparam = new CCodeParameter (get_delegate_target_cname ("result"), "void**");
cparam_map.set (get_param_pos (get_ccode_delegate_target_pos (d)), cparam);
- if (deleg_type.value_owned) {
+ if (deleg_type.is_disposable ()) {
cparam = new CCodeParameter (get_delegate_target_destroy_notify_cname ("result"), "GDestroyNotify*");
cparam_map.set (get_param_pos (get_ccode_delegate_target_pos (d) + 0.01), cparam);
}
if (deleg_type.delegate_symbol.has_target) {
var ctarget = new CCodeIdentifier (get_ccode_delegate_target_name (d_params.get (i)));
carg_map.set (get_param_pos (get_ccode_delegate_target_pos (param)), ctarget);
- if (deleg_type.value_owned) {
+ if (deleg_type.is_disposable ()) {
var ctarget_destroy_notify = new CCodeIdentifier (get_delegate_target_destroy_notify_cname (d_params.get (i).name));
carg_map.set (get_param_pos (get_ccode_delegate_target_pos (m) + 0.01), ctarget_destroy_notify);
}
if (deleg_type.delegate_symbol.has_target) {
var ctarget = new CCodeIdentifier (get_delegate_target_cname ("result"));
carg_map.set (get_param_pos (get_ccode_delegate_target_pos (m)), ctarget);
- if (deleg_type.value_owned) {
+ if (deleg_type.is_disposable ()) {
var ctarget_destroy_notify = new CCodeIdentifier (get_delegate_target_destroy_notify_cname ("result"));
carg_map.set (get_param_pos (get_ccode_delegate_target_pos (m) + 0.01), ctarget_destroy_notify);
}
if (carg_map != null) {
carg_map.set (get_param_pos (get_ccode_delegate_target_pos (param)), get_variable_cexpression (cparam.name));
}
- if (deleg_type.value_owned) {
+ if (deleg_type.is_disposable ()) {
cparam = new CCodeParameter (get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)), target_destroy_notify_ctypename);
cparam_map.set (get_param_pos (get_ccode_delegate_target_pos (param) + 0.01), cparam);
if (carg_map != null) {
var ref_call = new CCodeFunctionCall (get_dup_func_expression (expr.inner.value_type, expr.source_reference));
ref_call.add_argument (delegate_target);
delegate_target = ref_call;
- set_delegate_target_destroy_notify (expr, get_destroy_func_expression (expr.inner.value_type));
+ if (delegate_type != null && delegate_type.is_disposable ()) {
+ set_delegate_target_destroy_notify (expr, get_destroy_func_expression (expr.inner.value_type));
+ }
}
set_delegate_target (expr, delegate_target);
}
}
} else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
result.delegate_target_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_local_cname (local)));
- if (delegate_type.value_owned) {
+ if (delegate_type.is_disposable ()) {
result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_destroy_notify_cname (get_local_cname (local)));
}
}
}
} else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
result.delegate_target_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_ccode_delegate_target_name (param));
- if (result.value_type.value_owned) {
+ if (result.value_type.is_disposable ()) {
result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
}
}
result.cvalue = get_variable_cexpression (param.name);
if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
result.delegate_target_cvalue = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), get_ccode_delegate_target_name (param));
- if (delegate_type.value_owned) {
+ if (delegate_type.is_disposable ()) {
result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (new CCodeIdentifier ("_data_"), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
}
}
delegate_target_destroy_notify = new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, delegate_target_destroy_notify);
}
result.delegate_target_cvalue = target_expr;
- if (result.value_type.value_owned) {
+ if (result.value_type.is_disposable ()) {
result.delegate_target_destroy_notify_cvalue = delegate_target_destroy_notify;
}
}
if (((TypeSymbol) field.parent_symbol).is_reference_type ()) {
result.delegate_target_cvalue = new CCodeMemberAccess.pointer (inst, target_cname);
- if (result.value_type.value_owned) {
+ if (result.value_type.is_disposable ()){
result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (inst, target_destroy_notify_cname);
}
} else {
result.delegate_target_cvalue = new CCodeMemberAccess (inst, target_cname);
- if (result.value_type.value_owned) {
+ if (result.value_type.is_disposable ()) {
result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess (inst, target_destroy_notify_cname);
}
}
}
} else if (delegate_type != null && delegate_type.delegate_symbol.has_target && get_ccode_delegate_target (field)) {
result.delegate_target_cvalue = new CCodeIdentifier (get_ccode_delegate_target_name (field));
- if (result.value_type.value_owned) {
+ if (result.value_type.is_disposable ()) {
result.delegate_target_destroy_notify_cvalue = new CCodeIdentifier (get_delegate_target_destroy_notify_cname (get_ccode_name (field)));
}
}
cexpr = new CCodeConditionalExpression (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, cexpr, new CCodeIdentifier ("NULL")), new CCodeIdentifier ("NULL"), closure_new);
} else {
carg_map.set (get_param_pos (get_ccode_delegate_target_pos (param)), delegate_target);
- if (deleg_type.value_owned && !deleg_type.is_called_once) {
+ if (deleg_type.is_disposable ()) {
assert (delegate_target_destroy_notify != null);
carg_map.set (get_param_pos (get_ccode_delegate_target_pos (param) + 0.01), delegate_target_destroy_notify);
}
emit_temp_var (temp_var);
set_delegate_target (arg, get_variable_cexpression (temp_var.name));
carg_map.set (get_param_pos (get_ccode_delegate_target_pos (param)), new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, get_delegate_target (arg)));
- if (deleg_type.value_owned) {
+ if (deleg_type.is_disposable ()) {
temp_var = get_temp_variable (gdestroynotify_type);
emit_temp_var (temp_var);
set_delegate_target_destroy_notify (arg, get_variable_cexpression (temp_var.name));
set_delegate_target (expr, temp_ref);
- if (deleg_type.value_owned) {
+ if (deleg_type.is_disposable ()) {
temp_var = get_temp_variable (gdestroynotify_type);
temp_ref = get_variable_cexpression (temp_var.name);
if (carg_map != null) {
carg_map.set (get_param_pos (get_ccode_delegate_target_pos (m)), get_variable_cexpression (cparam.name));
}
- if (deleg_type.value_owned) {
+ if (deleg_type.is_disposable ()) {
cparam = new CCodeParameter (get_delegate_target_destroy_notify_cname ("result"), "GDestroyNotify*");
cparam_map.set (get_param_pos (get_ccode_delegate_target_pos (m) + 0.01), cparam);
if (carg_map != null) {
vardecl = new CCodeVariableDeclarator.zero ("_vala_" + get_ccode_delegate_target_name (param), new CCodeConstant ("NULL"));
ccode.add_declaration ("void *", vardecl);
- if (deleg_type.value_owned) {
+ if (deleg_type.is_disposable ()) {
vardecl = new CCodeVariableDeclarator.zero (get_delegate_target_destroy_notify_cname (get_variable_cname ("_vala_" + param.name)), new CCodeConstant ("NULL"));
ccode.add_declaration ("GDestroyNotify", vardecl);
}
if (delegate_type.delegate_symbol.has_target) {
// create field to store delegate target
instance_struct.add_field ("gpointer", get_ccode_delegate_target_name (f));
- if (delegate_type.value_owned) {
+ if (delegate_type.is_disposable ()) {
instance_struct.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (f.name));
}
}
if (delegate_type.delegate_symbol.has_target) {
// create field to store delegate target
instance_struct.add_field ("gpointer", get_ccode_delegate_target_name (f));
- if (delegate_type.value_owned) {
+ if (delegate_type.is_disposable ()) {
instance_struct.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (f.name));
}
}
if (delegate_type.delegate_symbol.has_target) {
// create field to store delegate target
instance_priv_struct.add_field ("gpointer", get_ccode_delegate_target_name (f));
- if (delegate_type.value_owned) {
+ if (delegate_type.is_disposable ()) {
instance_priv_struct.add_field ("GDestroyNotify", get_delegate_target_destroy_notify_cname (f.name));
}
}
delegates/bug595639.vala \
delegates/bug638415.vala \
delegates/bug639751.vala \
+ delegates/bug703804.vala \
objects/classes.vala \
objects/fields.vala \
objects/interfaces.vala \
--- /dev/null
+[CCode (scope = "async")]
+public delegate void Run();
+
+static void eval(owned Run run) {
+ Run own = (owned) run;
+ own ();
+}
+
+void main() {
+ int i = 0;
+ eval(() => {
+ i++;
+ });
+ assert(i == 1);
+}
}
public override bool is_disposable () {
- return delegate_symbol.has_target && value_owned;
+ return delegate_symbol.has_target && value_owned && !is_called_once;
}
}
return false;
}
+ var is_owned_delegate = inner.value_type is DelegateType && inner.value_type.value_owned;
if (!inner.value_type.is_disposable ()
- && !(inner.value_type is PointerType)) {
+ && !(inner.value_type is PointerType)
+ && !is_owned_delegate) {
error = true;
Report.error (source_reference, "No reference to be transferred");
return false;