[vala] codegen: Allow scope=async delegates to be used in vala code
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] codegen: Allow scope=async delegates to be used in vala code
- Date: Sun, 14 Jul 2013 07:37:26 +0000 (UTC)
commit 6d07669384cdb70c3c657dba67d5048212f25da9
Author: Luca Bruno <lucabru src gnome org>
Date: Thu Jul 11 22:39:53 2013 +0200
codegen: Allow scope=async delegates to be used in vala code
Fixes bug 703804
codegen/valaccodeassignmentmodule.vala | 10 ++++++++--
codegen/valaccodebasemodule.vala | 14 +++++++-------
codegen/valaccodedelegatemodule.vala | 12 ++++++------
codegen/valaccodememberaccessmodule.vala | 18 ++++++++++--------
codegen/valaccodemethodcallmodule.vala | 6 +++---
codegen/valaccodemethodmodule.vala | 4 ++--
codegen/valaccodestructmodule.vala | 2 +-
codegen/valagtypemodule.vala | 4 ++--
tests/Makefile.am | 1 +
tests/delegates/bug703804.vala | 15 +++++++++++++++
vala/valadelegatetype.vala | 2 +-
vala/valareferencetransferexpression.vala | 4 +++-
12 files changed, 59 insertions(+), 33 deletions(-)
---
diff --git a/codegen/valaccodeassignmentmodule.vala b/codegen/valaccodeassignmentmodule.vala
index 21a2d42..67be9c9 100644
--- a/codegen/valaccodeassignmentmodule.vala
+++ b/codegen/valaccodeassignmentmodule.vala
@@ -149,8 +149,14 @@ public class Vala.CCodeAssignmentModule : CCodeMemberAccessModule {
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"));
+ }
}
}
}
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 1a90ec0..e42c578 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -1048,7 +1048,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
}
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 ()) {
@@ -1250,7 +1250,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
}
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 ()) {
@@ -1823,7 +1823,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
}
} 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);
@@ -2416,7 +2416,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
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;
}
@@ -3543,7 +3543,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
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)));
}
}
@@ -3612,7 +3612,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
}
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);
@@ -4583,7 +4583,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
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);
}
}
diff --git a/codegen/valaccodedelegatemodule.vala b/codegen/valaccodedelegatemodule.vala
index 959bdcb..cf367a5 100644
--- a/codegen/valaccodedelegatemodule.vala
+++ b/codegen/valaccodedelegatemodule.vala
@@ -73,7 +73,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
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);
}
@@ -97,7 +97,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
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);
}
@@ -248,7 +248,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
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);
}
@@ -341,7 +341,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
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);
}
@@ -367,7 +367,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
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);
}
@@ -478,7 +478,7 @@ public class Vala.CCodeDelegateModule : CCodeArrayModule {
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) {
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index 6becb19..82f9d06 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -100,7 +100,9 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
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);
}
@@ -360,7 +362,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
}
} 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)));
}
}
@@ -437,7 +439,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
}
} 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)));
}
}
@@ -446,7 +448,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
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)));
}
}
@@ -487,7 +489,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
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;
}
}
@@ -589,12 +591,12 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
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);
}
}
@@ -651,7 +653,7 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
}
} 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)));
}
}
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 5d968b0..0bd462a 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -364,7 +364,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
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);
}
@@ -420,7 +420,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
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));
@@ -514,7 +514,7 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
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);
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 94edfe1..0dc6963 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -100,7 +100,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
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) {
@@ -582,7 +582,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
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);
}
diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala
index df33939..51cef5d 100644
--- a/codegen/valaccodestructmodule.vala
+++ b/codegen/valaccodestructmodule.vala
@@ -102,7 +102,7 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
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));
}
}
diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala
index 552d4e6..67d1051 100644
--- a/codegen/valagtypemodule.vala
+++ b/codegen/valagtypemodule.vala
@@ -341,7 +341,7 @@ public class Vala.GTypeModule : GErrorModule {
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));
}
}
@@ -447,7 +447,7 @@ public class Vala.GTypeModule : GErrorModule {
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));
}
}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 07c505e..8a0df29 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -98,6 +98,7 @@ TESTS = \
delegates/bug595639.vala \
delegates/bug638415.vala \
delegates/bug639751.vala \
+ delegates/bug703804.vala \
objects/classes.vala \
objects/fields.vala \
objects/interfaces.vala \
diff --git a/tests/delegates/bug703804.vala b/tests/delegates/bug703804.vala
new file mode 100644
index 0000000..8bb2d15
--- /dev/null
+++ b/tests/delegates/bug703804.vala
@@ -0,0 +1,15 @@
+[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);
+}
diff --git a/vala/valadelegatetype.vala b/vala/valadelegatetype.vala
index 92bd1e2..704f98c 100644
--- a/vala/valadelegatetype.vala
+++ b/vala/valadelegatetype.vala
@@ -120,6 +120,6 @@ public class Vala.DelegateType : DataType {
}
public override bool is_disposable () {
- return delegate_symbol.has_target && value_owned;
+ return delegate_symbol.has_target && value_owned && !is_called_once;
}
}
diff --git a/vala/valareferencetransferexpression.vala b/vala/valareferencetransferexpression.vala
index cd2f154..7ceba6d 100644
--- a/vala/valareferencetransferexpression.vala
+++ b/vala/valareferencetransferexpression.vala
@@ -94,8 +94,10 @@ public class Vala.ReferenceTransferExpression : Expression {
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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]