]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
dova: Fix generic delegates
authorJürg Billeter <j@bitron.ch>
Thu, 8 Jul 2010 06:21:40 +0000 (08:21 +0200)
committerJürg Billeter <j@bitron.ch>
Thu, 8 Jul 2010 07:09:02 +0000 (09:09 +0200)
codegen/valadovabasemodule.vala
codegen/valadovaobjectmodule.vala

index 01ea90f79633231bbf3ce8b53527e90426c02b21..4e3662f46794b069f66fcf16d73e8ff7f1baf846 100644 (file)
@@ -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;
                }
 
index 678c79ee7fc687036aec2af05874c80b171f7b3d..c567daf5df7d845b5e47e114ba5c11b2d31db1c7 100644 (file)
@@ -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);
                }