2008-06-02 Jürg Billeter <j@bitron.ch>
+ * gobject/valaccodegenerator.vala:
+ * gobject/valaccodeinvocationexpressionbinding.vala:
+ * gobject/valaccodemethodbinding.vala:
+
+ Add basic support for owned delegates, fixes bug 533484
+
+2008-06-02 Jürg Billeter <j@bitron.ch>
+
* vapi/gmodule-2.0.vapi:
* vapi/sdl-gfx.vapi:
* vapi/sdl-mixer.vapi:
}
}
- private CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference) {
+ public CCodeExpression? get_dup_func_expression (DataType type, SourceReference? source_reference) {
var cl = type.data_type as Class;
if (type.data_type != null) {
string dup_function;
return dup_func;
}
- private CCodeExpression? get_destroy_func_expression (DataType type) {
+ public CCodeExpression? get_destroy_func_expression (DataType type) {
if (type.data_type == glist_type || type.data_type == gslist_type) {
// create wrapper function to free list elements if necessary
return new CCodeConstant ("NULL");
}
+ public string get_delegate_target_destroy_notify_cname (string delegate_cname) {
+ return "%s_target_destroy_notify".printf (delegate_cname);
+ }
+
public override void visit_element_access (ElementAccess expr) {
code_binding (expr).emit ();
}
var deleg_type = (DelegateType) param.parameter_type;
var d = deleg_type.delegate_symbol;
if (d.has_target) {
- carg_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), codegen.get_delegate_target_cexpression (arg));
+ var delegate_target = codegen.get_delegate_target_cexpression (arg);
+ if (deleg_type.value_owned) {
+ CCodeExpression delegate_target_destroy_notify;
+ var delegate_method = arg.symbol_reference as Method;
+ var ma = arg as MemberAccess;
+ if (delegate_method != null && delegate_method.binding == MemberBinding.INSTANCE
+ && ma.inner != null && ma.inner.value_type.data_type != null
+ && ma.inner.value_type.data_type.is_reference_counting ()) {
+ var ref_call = new CCodeFunctionCall (codegen.get_dup_func_expression (ma.inner.value_type, arg.source_reference));
+ ref_call.add_argument (delegate_target);
+ delegate_target = ref_call;
+ delegate_target_destroy_notify = codegen.get_destroy_func_expression (ma.inner.value_type);
+ } else {
+ delegate_target_destroy_notify = new CCodeConstant ("NULL");
+ }
+ carg_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position + 0.01), delegate_target_destroy_notify);
+ }
+ carg_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), delegate_target);
multiple_cargs = true;
}
} else if (param.parameter_type is MethodType) {
var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname (param.name), "void*");
cparam_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), cparam);
carg_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), new CCodeIdentifier (cparam.name));
+ if (deleg_type.value_owned) {
+ cparam = new CCodeFormalParameter (codegen.get_delegate_target_destroy_notify_cname (param.name), "GDestroyNotify");
+ cparam_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position + 0.01), cparam);
+ carg_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position + 0.01), new CCodeIdentifier (cparam.name));
+ }
}
}
}
if (d.has_target) {
var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname (param.name), "void*");
cparam_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position), cparam);
+ if (deleg_type.value_owned) {
+ cparam = new CCodeFormalParameter (codegen.get_delegate_target_destroy_notify_cname (param.name), "GDestroyNotify");
+ cparam_map.set (codegen.get_param_pos (param.cdelegate_target_parameter_position + 0.01), cparam);
+ }
}
} else if (param.parameter_type is MethodType) {
var cparam = new CCodeFormalParameter (codegen.get_delegate_target_cname (param.name), "void*");