[vala] dova: Fix generic delegates



commit b081cf1599ac89929d28add9ab12b583ccef66c2
Author: Jürg Billeter <j bitron ch>
Date:   Thu Jul 8 08:21:40 2010 +0200

    dova: Fix generic delegates

 codegen/valadovabasemodule.vala   |   45 ++++++++++++++++++++++++++++++++++++-
 codegen/valadovaobjectmodule.vala |   12 +++++++++-
 2 files changed, 55 insertions(+), 2 deletions(-)
---
diff --git a/codegen/valadovabasemodule.vala b/codegen/valadovabasemodule.vala
index 01ea90f..4e3662f 100644
--- a/codegen/valadovabasemodule.vala
+++ b/codegen/valadovabasemodule.vala
@@ -132,6 +132,7 @@ internal class Vala.DovaBaseModule : CCodeModule {
 	Set<string> reserved_identifiers;
 
 	public int next_temp_var_id = 0;
+	public int next_wrapper_id = 0;
 	public int next_string_const_id = 0;
 	public bool in_creation_method { get { return current_method is CreationMethod; } }
 	public bool current_method_inner_error = false;
@@ -2252,9 +2253,51 @@ internal class Vala.DovaBaseModule : CCodeModule {
 					delegate_target = new CCodeConstant ("NULL");
 				}
 			}
+
+			var d = deleg_type.delegate_symbol;
+
+			string wrapper_name = "_wrapper%d_".printf (next_wrapper_id++);
+			var wrapper = new CCodeFunction (wrapper_name);
+			var call = new CCodeFunctionCall (source_cexpr);
+
+			if (method_type.method_symbol.binding == MemberBinding.INSTANCE) {
+				wrapper.add_parameter (new CCodeFormalParameter ("this", "void *"));
+				call.add_argument (new CCodeIdentifier ("this"));
+			}
+
+			var method_param_iter = method_type.method_symbol.get_parameters ().iterator ();
+			foreach (FormalParameter param in d.get_parameters ()) {
+				method_param_iter.next ();
+				var method_param = method_param_iter.get ();
+				string ctype = param.parameter_type.get_cname ();
+				if (param.parameter_type is GenericType && !(method_param.parameter_type is GenericType)) {
+					ctype = method_param.parameter_type.get_cname () + "*";
+					call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier (param.name)));
+				} else if (!(param.parameter_type is GenericType) && method_param.parameter_type is GenericType) {
+					call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier (param.name)));
+				} else {
+					call.add_argument (new CCodeIdentifier (param.name));
+				}
+
+				wrapper.add_parameter (new CCodeFormalParameter (param.name, ctype));
+			}
+
+			wrapper.block = new CCodeBlock ();
+			if (d.return_type is GenericType) {
+				wrapper.add_parameter (new CCodeFormalParameter ("result", "void *"));
+				wrapper.block.add_statement (new CCodeExpressionStatement (call));
+			} else if (d.return_type is VoidType) {
+				wrapper.block.add_statement (new CCodeExpressionStatement (call));
+			} else {
+				wrapper.return_type = d.return_type.get_cname ();
+				wrapper.block.add_statement (new CCodeReturnStatement (call));
+			}
+
+			source_type_member_definition.append (wrapper);
+
 			var ccall = new CCodeFunctionCall (new CCodeIdentifier ("%s_new".printf (deleg_type.delegate_symbol.get_lower_case_cname ())));
 			ccall.add_argument (delegate_target);
-			ccall.add_argument (source_cexpr);
+			ccall.add_argument (new CCodeIdentifier (wrapper_name));
 			return ccall;
 		}
 
diff --git a/codegen/valadovaobjectmodule.vala b/codegen/valadovaobjectmodule.vala
index 678c79e..c567daf 100644
--- a/codegen/valadovaobjectmodule.vala
+++ b/codegen/valadovaobjectmodule.vala
@@ -1671,8 +1671,18 @@ internal class Vala.DovaObjectModule : DovaArrayModule {
 
 				var ccontainer = new CCodeFunctionCall (new CCodeIdentifier ("dova_array_get_data"));
 				ccontainer.add_argument ((CCodeExpression) expr.container.ccodenode);
-				expr.ccodenode = new CCodeElementAccess (new CCodeCastExpression (ccontainer, "%s*".printf (array_type.element_type.get_cname ())), cindex);
+
+				if (array_type.element_type is GenericType) {
+					// generic array
+					// calculate offset in bytes based on value size
+					var value_size = new CCodeFunctionCall (new CCodeIdentifier ("dova_type_get_value_size"));
+					value_size.add_argument (get_type_id_expression (array_type.element_type));
+					expr.ccodenode = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, new CCodeCastExpression (ccontainer, "char*"), new CCodeBinaryExpression (CCodeBinaryOperator.MUL, value_size, cindex));
+				} else {
+					expr.ccodenode = new CCodeElementAccess (new CCodeCastExpression (ccontainer, "%s*".printf (array_type.element_type.get_cname ())), cindex);
+				}
 			}
+
 		} else {
 			base.visit_element_access (expr);
 		}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]