summaryrefslogtreecommitdiff
path: root/codegen/valagsignalmodule.vala
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2020-04-12 11:02:29 +0200
committerRico Tzschichholz <ricotz@ubuntu.com>2020-04-12 11:09:34 +0200
commitbcc40d5b971c3f5e3ebe928890b9aeba5ba32ba8 (patch)
treeb87e86350217b757dd0baefaa14abcab8ce6a41a /codegen/valagsignalmodule.vala
parent34a47ef9f37aa1b53a72ff05862e88082ca952c0 (diff)
downloadvala-bcc40d5b971c3f5e3ebe928890b9aeba5ba32ba8.tar.gz
codegen: Correctly handle signals returning real non-nullable struct
Fixes https://gitlab.gnome.org/GNOME/vala/issues/466
Diffstat (limited to 'codegen/valagsignalmodule.vala')
-rw-r--r--codegen/valagsignalmodule.vala89
1 files changed, 60 insertions, 29 deletions
diff --git a/codegen/valagsignalmodule.vala b/codegen/valagsignalmodule.vala
index 909131775..108622815 100644
--- a/codegen/valagsignalmodule.vala
+++ b/codegen/valagsignalmodule.vala
@@ -24,8 +24,8 @@
public class Vala.GSignalModule : GObjectModule {
- string get_marshaller_function (List<Parameter> params, DataType return_type, string? prefix = null) {
- var signature = get_marshaller_signature (params, return_type);
+ string get_marshaller_function (Signal sig, List<Parameter> params, DataType return_type, string? prefix = null) {
+ var signature = get_marshaller_signature (sig, params, return_type);
string ret;
if (prefix == null) {
@@ -38,12 +38,13 @@ public class Vala.GSignalModule : GObjectModule {
ret = "%s_%s_".printf (prefix, get_ccode_marshaller_type_name (return_type));
- if (params == null || params.size == 0) {
+ foreach (Parameter p in params) {
+ ret = "%s_%s".printf (ret, get_ccode_marshaller_type_name (p).replace (",", "_"));
+ }
+ if (sig.return_type.is_real_non_null_struct_type ()) {
+ ret = ret + "_POINTER";
+ } else if (params.size == 0) {
ret = ret + "_VOID";
- } else {
- foreach (Parameter p in params) {
- ret = "%s_%s".printf (ret, get_ccode_marshaller_type_name (p).replace (",", "_"));
- }
}
return ret;
@@ -93,23 +94,24 @@ public class Vala.GSignalModule : GObjectModule {
}
}
- private string get_marshaller_signature (List<Parameter> params, DataType return_type) {
+ private string get_marshaller_signature (Signal sig, List<Parameter> params, DataType return_type) {
string signature;
signature = "%s:".printf (get_ccode_marshaller_type_name (return_type));
- if (params == null || params.size == 0) {
- signature = signature + "VOID";
- } else {
- bool first = true;
- foreach (Parameter p in params) {
- if (first) {
- signature = signature + get_ccode_marshaller_type_name (p);
- first = false;
- } else {
- signature = "%s,%s".printf (signature, get_ccode_marshaller_type_name (p));
- }
+ bool first = true;
+ foreach (Parameter p in params) {
+ if (first) {
+ signature = signature + get_ccode_marshaller_type_name (p);
+ first = false;
+ } else {
+ signature = "%s,%s".printf (signature, get_ccode_marshaller_type_name (p));
}
}
+ if (sig.return_type.is_real_non_null_struct_type ()) {
+ signature = signature + (first ? "POINTER" : ",POINTER");
+ } else if (params.size == 0) {
+ signature = signature + "VOID";
+ }
return signature;
}
@@ -164,24 +166,29 @@ public class Vala.GSignalModule : GObjectModule {
sig.accept_children (this);
// declare parameter type
- foreach (Parameter p in sig.get_parameters ()) {
+ unowned List<Parameter> params = sig.get_parameters ();
+ foreach (Parameter p in params) {
generate_parameter (p, cfile, new HashMap<int,CCodeParameter> (), null);
}
- generate_marshaller (sig.get_parameters (), sig.return_type);
+ if (sig.return_type.is_real_non_null_struct_type ()) {
+ generate_marshaller (sig, params, new VoidType ());
+ } else {
+ generate_marshaller (sig, params, sig.return_type);
+ }
}
- void generate_marshaller (List<Parameter> params, DataType return_type) {
+ void generate_marshaller (Signal sig, List<Parameter> params, DataType return_type) {
string signature;
int n_params, i;
/* check whether a signal with the same signature already exists for this source file (or predefined) */
- signature = get_marshaller_signature (params, return_type);
+ signature = get_marshaller_signature (sig, params, return_type);
if (predefined_marshal_set.contains (signature) || user_marshal_set.contains (signature)) {
return;
}
- var signal_marshaller = new CCodeFunction (get_marshaller_function (params, return_type, null), "void");
+ var signal_marshaller = new CCodeFunction (get_marshaller_function (sig, params, return_type, null), "void");
signal_marshaller.modifiers = CCodeModifiers.STATIC;
signal_marshaller.add_parameter (new CCodeParameter ("closure", "GClosure *"));
@@ -193,7 +200,7 @@ public class Vala.GSignalModule : GObjectModule {
push_function (signal_marshaller);
- var callback_decl = new CCodeFunctionDeclarator (get_marshaller_function (params, return_type, "GMarshalFunc"));
+ var callback_decl = new CCodeFunctionDeclarator (get_marshaller_function (sig, params, return_type, "GMarshalFunc"));
callback_decl.add_parameter (new CCodeParameter ("data1", "gpointer"));
n_params = 1;
foreach (Parameter p in params) {
@@ -218,10 +225,15 @@ public class Vala.GSignalModule : GObjectModule {
}
}
}
+ if (sig.return_type.is_real_non_null_struct_type ()) {
+ callback_decl.add_parameter (new CCodeParameter ("arg_%d".printf (n_params), "gpointer"));
+ n_params++;
+ }
+
callback_decl.add_parameter (new CCodeParameter ("data2", "gpointer"));
ccode.add_statement (new CCodeTypeDefinition (get_value_type_name_from_type_reference (return_type), callback_decl));
- ccode.add_declaration (get_marshaller_function (params, return_type, "GMarshalFunc"), new CCodeVariableDeclarator ("callback"), CCodeModifiers.REGISTER);
+ ccode.add_declaration (get_marshaller_function (sig, params, return_type, "GMarshalFunc"), new CCodeVariableDeclarator ("callback"), CCodeModifiers.REGISTER);
ccode.add_declaration ("GCClosure *", new CCodeVariableDeclarator ("cc", new CCodeCastExpression (new CCodeIdentifier ("closure"), "GCClosure *")), CCodeModifiers.REGISTER);
@@ -254,7 +266,7 @@ public class Vala.GSignalModule : GObjectModule {
ccode.add_assignment (new CCodeIdentifier ("data2"), data);
ccode.close ();
- var c_assign_rhs = new CCodeCastExpression (new CCodeConditionalExpression (new CCodeIdentifier ("marshal_data"), new CCodeIdentifier ("marshal_data"), new CCodeMemberAccess (new CCodeIdentifier ("cc"), "callback", true)), get_marshaller_function (params, return_type, "GMarshalFunc"));
+ var c_assign_rhs = new CCodeCastExpression (new CCodeConditionalExpression (new CCodeIdentifier ("marshal_data"), new CCodeIdentifier ("marshal_data"), new CCodeMemberAccess (new CCodeIdentifier ("cc"), "callback", true)), get_marshaller_function (sig, params, return_type, "GMarshalFunc"));
ccode.add_assignment (new CCodeIdentifier ("callback"), c_assign_rhs);
fc = new CCodeFunctionCall (new CCodeIdentifier ("callback"));
@@ -298,6 +310,12 @@ public class Vala.GSignalModule : GObjectModule {
}
}
}
+ if (sig.return_type.is_real_non_null_struct_type ()) {
+ var inner_fc = new CCodeFunctionCall (new CCodeIdentifier ("g_value_get_pointer"));
+ inner_fc.add_argument (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeIdentifier ("param_values"), new CCodeIdentifier (i.to_string ())));
+ fc.add_argument (inner_fc);
+ i++;
+ }
fc.add_argument (new CCodeIdentifier ("data2"));
if (return_type.type_symbol != null || return_type is ArrayType) {
@@ -379,12 +397,17 @@ public class Vala.GSignalModule : GObjectModule {
csignew.add_argument (new CCodeConstant ("NULL"));
csignew.add_argument (new CCodeConstant ("NULL"));
- string marshaller = get_marshaller_function (sig.get_parameters (), sig.return_type);
+ unowned List<Parameter> params = sig.get_parameters ();
+ string marshaller;
+ if (sig.return_type.is_real_non_null_struct_type ()) {
+ marshaller = get_marshaller_function (sig, params, new VoidType ());
+ } else {
+ marshaller = get_marshaller_function (sig, params, sig.return_type);
+ }
var marshal_arg = new CCodeIdentifier (marshaller);
csignew.add_argument (marshal_arg);
- var params = sig.get_parameters ();
if (sig.return_type is PointerType || sig.return_type is GenericType) {
csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
} else if (sig.return_type is ErrorType) {
@@ -393,6 +416,8 @@ public class Vala.GSignalModule : GObjectModule {
csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
} else if (sig.return_type.type_symbol == null) {
csignew.add_argument (new CCodeConstant ("G_TYPE_NONE"));
+ } else if (sig.return_type.is_real_non_null_struct_type ()) {
+ csignew.add_argument (new CCodeConstant ("G_TYPE_NONE"));
} else {
csignew.add_argument (new CCodeConstant (get_ccode_type_id (sig.return_type.type_symbol)));
}
@@ -412,6 +437,9 @@ public class Vala.GSignalModule : GObjectModule {
}
}
}
+ if (sig.return_type.is_real_non_null_struct_type ()) {
+ params_len++;
+ }
csignew.add_argument (new CCodeConstant ("%d".printf (params_len)));
foreach (Parameter param in params) {
@@ -446,6 +474,9 @@ public class Vala.GSignalModule : GObjectModule {
csignew.add_argument (new CCodeConstant (get_ccode_type_id (param.variable_type.type_symbol)));
}
}
+ if (sig.return_type.is_real_non_null_struct_type ()) {
+ csignew.add_argument (new CCodeConstant ("G_TYPE_POINTER"));
+ }
marshal_arg.name = marshaller;