Beispiel #1
0
        public override void generate_virtual_method_declaration(Method m, CCodeFile decl_space, CCodeStruct type_struct)
        {
            if (!m.coroutine)
            {
                base.generate_virtual_method_declaration(m, decl_space, type_struct);
                return;
            }

            if (!m.is_abstract && !m.is_virtual)
            {
                return;
            }

            var creturn_type = m.return_type;

            if (m.return_type.is_real_non_null_struct_type())
            {
                // structs are returned via out parameter
                creturn_type = new VoidType();
            }

            // add vfunc field to the type struct
            var vdeclarator = new CCodeFunctionDeclarator(get_ccode_vfunc_name(m));
            var cparam_map  = new Dictionary <int, CCodeParameter>();

            generate_cparameters(m, decl_space, cparam_map, new CCodeFunction("fake"), vdeclarator, null, null, 1);

            var vdecl = new CCodeDeclaration("void");

            vdecl.add_declarator(vdeclarator);
            type_struct.add_declaration(vdecl);

            // add vfunc field to the type struct
            vdeclarator = new CCodeFunctionDeclarator(get_ccode_finish_vfunc_name(m));
            cparam_map  = new Dictionary <int, CCodeParameter>();

            generate_cparameters(m, decl_space, cparam_map, new CCodeFunction("fake"), vdeclarator, null, null, 2);

            vdecl = new CCodeDeclaration(get_ccode_name(creturn_type));
            vdecl.add_declarator(vdeclarator);
            type_struct.add_declaration(vdecl);
        }
Beispiel #2
0
        void generate_marshaller(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);
            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");

            signal_marshaller.modifiers = CCodeModifiers.STATIC;

            signal_marshaller.add_parameter(new CCodeParameter("closure", "GClosure *"));
            signal_marshaller.add_parameter(new CCodeParameter("return_value", "GValue *"));
            signal_marshaller.add_parameter(new CCodeParameter("n_param_values", "guint"));
            signal_marshaller.add_parameter(new CCodeParameter("param_values", "const GValue *"));
            signal_marshaller.add_parameter(new CCodeParameter("invocation_hint", "gpointer"));
            signal_marshaller.add_parameter(new CCodeParameter("marshal_data", "gpointer"));

            push_function(signal_marshaller);

            var callback_decl = new CCodeFunctionDeclarator(get_marshaller_function(_params, return_type, "GMarshalFunc"));

            callback_decl.add_parameter(new CCodeParameter("data1", "gpointer"));
            n_params = 1;
            foreach (Parameter p in _params)
            {
                callback_decl.add_parameter(new CCodeParameter("arg_%d".printf(n_params), get_value_type_name_from_parameter(p)));
                n_params++;
                if (p.variable_type.is_array())
                {
                    for (var j = 0; j < ((ArrayType)p.variable_type).rank; j++)
                    {
                        callback_decl.add_parameter(new CCodeParameter("arg_%d".printf(n_params), "gint"));
                        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("GCClosure *", new CCodeVariableDeclarator("cc", new CCodeCastExpression(new CCodeIdentifier("closure"), "GCClosure *")), CCodeModifiers.REGISTER);

            ccode.add_declaration("gpointer", new CCodeVariableDeclarator("data1"), CCodeModifiers.REGISTER);
            ccode.add_declaration("gpointer", new CCodeVariableDeclarator("data2"), CCodeModifiers.REGISTER);

            CCodeFunctionCall fc;

            if (return_type.data_type != null || return_type.is_array())
            {
                ccode.add_declaration(get_value_type_name_from_type_reference(return_type), new CCodeVariableDeclarator("v_return"));

                fc = new CCodeFunctionCall(new CCodeIdentifier("g_return_if_fail"));
                fc.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier("return_value"), new CCodeConstant("NULL")));
                ccode.add_expression(fc);
            }

            fc = new CCodeFunctionCall(new CCodeIdentifier("g_return_if_fail"));
            fc.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.EQUALITY, new CCodeIdentifier("n_param_values"), new CCodeConstant(n_params.ToString())));
            ccode.add_expression(fc);

            var data  = new CCodeMemberAccess(new CCodeIdentifier("closure"), "data", true);
            var param = new CCodeMemberAccess(new CCodeMemberAccess(new CCodeIdentifier("param_values"), "data[0]", true), "v_pointer");
            var cond  = new CCodeFunctionCall(new CCodeConstant("G_CCLOSURE_SWAP_DATA"));

            cond.add_argument(new CCodeIdentifier("closure"));
            ccode.open_if(cond);
            ccode.add_assignment(new CCodeIdentifier("data1"), data);
            ccode.add_assignment(new CCodeIdentifier("data2"), param);
            ccode.add_else();
            ccode.add_assignment(new CCodeIdentifier("data1"), param);
            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"));

            ccode.add_assignment(new CCodeIdentifier("callback"), c_assign_rhs);

            fc = new CCodeFunctionCall(new CCodeIdentifier("callback"));
            fc.add_argument(new CCodeIdentifier("data1"));
            i = 1;
            foreach (Parameter p in _params)
            {
                string get_value_function;
                bool   is_array = p.variable_type.is_array();
                if (p.direction != ParameterDirection.IN)
                {
                    get_value_function = "g_value_get_pointer";
                }
                else if (is_array)
                {
                    if (((ArrayType)p.variable_type).element_type.data_type == string_type.data_type)
                    {
                        get_value_function = "g_value_get_boxed";
                    }
                    else
                    {
                        get_value_function = "g_value_get_pointer";
                    }
                }
                else if (p.variable_type is PointerType || p.variable_type.type_parameter != null)
                {
                    get_value_function = "g_value_get_pointer";
                }
                else if (p.variable_type is ErrorType)
                {
                    get_value_function = "g_value_get_pointer";
                }
                else if (p.variable_type is ValaValueType && p.variable_type.nullable)
                {
                    get_value_function = "g_value_get_pointer";
                }
                else
                {
                    get_value_function = get_ccode_get_value_function(p.variable_type.data_type);
                }
                var inner_fc = new CCodeFunctionCall(new CCodeIdentifier(get_value_function));
                inner_fc.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, new CCodeIdentifier("param_values"), new CCodeIdentifier(i.ToString())));
                fc.add_argument(inner_fc);
                i++;
                if (is_array)
                {
                    for (var j = 0; j < ((ArrayType)p.variable_type).rank; j++)
                    {
                        inner_fc = new CCodeFunctionCall(new CCodeIdentifier("g_value_get_int"));
                        inner_fc.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, new CCodeIdentifier("param_values"), new CCodeIdentifier(i.ToString())));
                        fc.add_argument(inner_fc);
                        i++;
                    }
                }
            }
            fc.add_argument(new CCodeIdentifier("data2"));

            if (return_type.data_type != null || return_type.is_array())
            {
                ccode.add_assignment(new CCodeIdentifier("v_return"), fc);

                CCodeFunctionCall set_fc;
                if (return_type.is_array())
                {
                    if (((ArrayType)return_type).element_type.data_type == string_type.data_type)
                    {
                        set_fc = new CCodeFunctionCall(new CCodeIdentifier("g_value_take_boxed"));
                    }
                    else
                    {
                        set_fc = new CCodeFunctionCall(new CCodeIdentifier("g_value_set_pointer"));
                    }
                }
                else if (return_type.type_parameter != null)
                {
                    set_fc = new CCodeFunctionCall(new CCodeIdentifier("g_value_set_pointer"));
                }
                else if (return_type is ErrorType)
                {
                    set_fc = new CCodeFunctionCall(new CCodeIdentifier("g_value_set_pointer"));
                }
                else if (return_type.data_type == string_type.data_type)
                {
                    set_fc = new CCodeFunctionCall(new CCodeIdentifier("g_value_take_string"));
                }
                else if (return_type.data_type is Class || return_type.data_type is Interface)
                {
                    set_fc = new CCodeFunctionCall(new CCodeIdentifier("g_value_take_object"));
                }
                else if (return_type is ValaValueType && return_type.nullable)
                {
                    set_fc = new CCodeFunctionCall(new CCodeIdentifier("g_value_set_pointer"));
                }
                else
                {
                    set_fc = new CCodeFunctionCall(new CCodeIdentifier(get_ccode_set_value_function(return_type.data_type)));
                }
                set_fc.add_argument(new CCodeIdentifier("return_value"));
                set_fc.add_argument(new CCodeIdentifier("v_return"));

                ccode.add_expression(set_fc);
            }
            else
            {
                ccode.add_expression(fc);
            }

            pop_function();

            cfile.add_function_declaration(signal_marshaller);
            cfile.add_function(signal_marshaller);
            user_marshal_set.Add(signature);
        }
        public override void generate_delegate_declaration(ValaDelegate d, CCodeFile decl_space)
        {
            if (add_symbol_declaration(decl_space, d, get_ccode_name(d)))
            {
                return;
            }

            string return_type_cname = get_ccode_name(d.return_type);

            if (d.return_type.is_real_non_null_struct_type())
            {
                // structs are returned via out parameter
                return_type_cname = "void";
            }

            if (return_type_cname == get_ccode_name(d))
            {
                // recursive delegate
                return_type_cname = "GCallback";
            }
            else
            {
                generate_type_declaration(d.return_type, decl_space);
            }

            var cfundecl = new CCodeFunctionDeclarator(get_ccode_name(d));

            foreach (Parameter param in d.get_parameters())
            {
                var cparam = generate_parameter(param, decl_space, new Dictionary <int, CCodeParameter>(), null);

                cfundecl.add_parameter(cparam);

                // handle array parameters
                if (get_ccode_array_length(param) && param.variable_type is ArrayType)
                {
                    var array_type = (ArrayType)param.variable_type;

                    var length_ctype = "int";
                    if (param.direction != ParameterDirection.IN)
                    {
                        length_ctype = "int*";
                    }

                    for (int dim = 1; dim <= array_type.rank; dim++)
                    {
                        cparam = new CCodeParameter(get_parameter_array_length_cname(param, dim), length_ctype);
                        cfundecl.add_parameter(cparam);
                    }
                }
                // handle delegate parameters
                if (param.variable_type is DelegateType)
                {
                    var deleg_type = (DelegateType)param.variable_type;
                    var param_d    = deleg_type.delegate_symbol;
                    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.is_disposable())
                        {
                            cparam = new CCodeParameter(get_delegate_target_destroy_notify_cname(get_variable_cname(param.name)), "GDestroyNotify*");
                            cfundecl.add_parameter(cparam);
                        }
                    }
                }
            }
            if (get_ccode_array_length(d) && d.return_type is ArrayType)
            {
                // return array length if appropriate
                var array_type        = (ArrayType)d.return_type;
                var array_length_type = get_ccode_array_length_type(d) != null?get_ccode_array_length_type(d) : "int";

                array_length_type += "*";

                for (int dim = 1; dim <= array_type.rank; dim++)
                {
                    var cparam = new CCodeParameter(get_array_length_cname("result", dim), array_length_type);
                    cfundecl.add_parameter(cparam);
                }
            }
            else if (d.return_type is DelegateType)
            {
                // return delegate target if appropriate
                var deleg_type = (DelegateType)d.return_type;
                var result_d   = deleg_type.delegate_symbol;
                if (result_d.has_target)
                {
                    var cparam = new CCodeParameter(get_delegate_target_cname("result"), "void**");
                    cfundecl.add_parameter(cparam);
                    if (deleg_type.is_disposable())
                    {
                        cparam = new CCodeParameter(get_delegate_target_destroy_notify_cname("result"), "GDestroyNotify*");
                        cfundecl.add_parameter(cparam);
                    }
                }
            }
            else if (d.return_type.is_real_non_null_struct_type())
            {
                var cparam = new CCodeParameter("result", "%s*".printf(get_ccode_name(d.return_type)));
                cfundecl.add_parameter(cparam);
            }
            if (d.has_target)
            {
                var cparam = new CCodeParameter("user_data", "void*");
                cfundecl.add_parameter(cparam);
            }
            if (d.get_error_types().Count > 0)
            {
                var cparam = new CCodeParameter("error", "GError**");
                cfundecl.add_parameter(cparam);
            }

            var ctypedef = new CCodeTypeDefinition(return_type_cname, cfundecl);

            ctypedef.modifiers |= (d.version.deprecated ? CCodeModifiers.DEPRECATED : 0);

            decl_space.add_type_definition(ctypedef);
        }
Beispiel #4
0
        public override void generate_cparameters(Method m, CCodeFile decl_space, Dictionary <int, CCodeParameter> cparam_map, CCodeFunction func, CCodeFunctionDeclarator vdeclarator = null, Dictionary <int, CCodeExpression> carg_map = null, CCodeFunctionCall vcall = null, int direction = 3)
        {
            if (m.coroutine)
            {
                decl_space.add_include("gio/gio.h");

                if (direction == 1)
                {
                    cparam_map[get_param_pos(-1)]   = new CCodeParameter("_callback_", "GAsyncReadyCallback");
                    cparam_map[get_param_pos(-0.9)] = new CCodeParameter("_user_data_", "gpointer");
                    if (carg_map != null)
                    {
                        carg_map[get_param_pos(-1)]   = new CCodeIdentifier("_callback_");
                        carg_map[get_param_pos(-0.9)] = new CCodeIdentifier("_user_data_");
                    }
                }
                else if (direction == 2)
                {
                    cparam_map[get_param_pos(0.1)] = new CCodeParameter("_res_", "GAsyncResult*");
                    if (carg_map != null)
                    {
                        carg_map[get_param_pos(0.1)] = new CCodeIdentifier("_res_");
                    }
                }
            }
            base.generate_cparameters(m, decl_space, cparam_map, func, vdeclarator, carg_map, vcall, direction);
        }