示例#1
0
        public override string get_dynamic_property_setter_cname(DynamicProperty prop)
        {
            if (prop.dynamic_type.data_type == null ||
                !prop.dynamic_type.data_type.is_subtype_of(gobject_type))
            {
                return(base.get_dynamic_property_setter_cname(prop));
            }

            string setter_cname = "_dynamic_set_%s%d".printf(prop.name, dynamic_property_id++);

            var func = new CCodeFunction(setter_cname, "void");

            func.modifiers |= CCodeModifiers.STATIC | CCodeModifiers.INLINE;
            func.add_parameter(new CCodeParameter("obj", get_ccode_name(prop.dynamic_type)));
            func.add_parameter(new CCodeParameter("value", get_ccode_name(prop.property_type)));

            push_function(func);

            var call = new CCodeFunctionCall(new CCodeIdentifier("g_object_set"));

            call.add_argument(new CCodeIdentifier("obj"));
            call.add_argument(get_property_canonical_cconstant(prop));
            call.add_argument(new CCodeIdentifier("value"));
            call.add_argument(new CCodeConstant("NULL"));

            ccode.add_expression(call);

            pop_function();

            // append to C source file
            cfile.add_function_declaration(func);
            cfile.add_function(func);

            return(setter_cname);
        }
示例#2
0
        public override void visit_error_domain(ErrorDomain edomain)
        {
            if (edomain.comment != null)
            {
                cfile.add_type_definition(new CCodeComment(edomain.comment.content));
            }

            generate_error_domain_declaration(edomain, cfile);

            if (!edomain.is_internal_symbol())
            {
                generate_error_domain_declaration(edomain, header_file);
            }
            if (!edomain.is_private_symbol())
            {
                generate_error_domain_declaration(edomain, internal_header_file);
            }

            string quark_fun_name = get_ccode_lower_case_prefix(edomain) + "quark";

            var cquark_fun = new CCodeFunction(quark_fun_name, get_ccode_name(gquark_type.data_type));

            push_function(cquark_fun);

            var cquark_call = new CCodeFunctionCall(new CCodeIdentifier("g_quark_from_static_string"));

            cquark_call.add_argument(new CCodeConstant("\"" + CCodeBaseModule.get_quark_name(edomain) + "\""));

            ccode.add_return(cquark_call);

            pop_function();
            cfile.add_function(cquark_fun);
        }
示例#3
0
        public override void return_with_exception(CCodeExpression error_expr)
        {
            if (!is_in_coroutine())
            {
                base.return_with_exception(error_expr);
                return;
            }

            var async_result_expr       = CCodeMemberAccess.pointer(new CCodeIdentifier("_data_"), "_async_result");
            CCodeFunctionCall set_error = null;

            set_error = new CCodeFunctionCall(new CCodeIdentifier("g_task_return_error"));
            set_error.add_argument(async_result_expr);
            set_error.add_argument(error_expr);
            ccode.add_expression(set_error);

            append_local_free(current_symbol, false);

            // We already returned the error above, we must not return anything else here.
            var unref = new CCodeFunctionCall(new CCodeIdentifier("g_object_unref"));

            unref.add_argument(async_result_expr);
            ccode.add_expression(unref);

            ccode.add_return(new CCodeConstant("FALSE"));
        }
示例#4
0
        CCodeExpression get_file_descriptor(DataType type, CCodeExpression expr)
        {
            if (type is ObjectType)
            {
                if (type.data_type.get_full_name() == "GLib.UnixInputStream")
                {
                    var result = new CCodeFunctionCall(new CCodeIdentifier("g_unix_input_stream_get_fd"));
                    result.add_argument(expr);
                    return(result);
                }
                else if (type.data_type.get_full_name() == "GLib.UnixOutputStream")
                {
                    var result = new CCodeFunctionCall(new CCodeIdentifier("g_unix_output_stream_get_fd"));
                    result.add_argument(expr);
                    return(result);
                }
                else if (type.data_type.get_full_name() == "GLib.Socket")
                {
                    var result = new CCodeFunctionCall(new CCodeIdentifier("g_socket_get_fd"));
                    result.add_argument(expr);
                    return(result);
                }
                else if (type.data_type.get_full_name() == "GLib.FileDescriptorBased")
                {
                    var result = new CCodeFunctionCall(new CCodeIdentifier("g_file_descriptor_based_get_fd"));
                    result.add_argument(expr);
                    return(result);
                }
            }

            return(null);
        }
示例#5
0
        private CCodeExpression get_signal_name_cexpression(Signal sig, Expression detail_expr, CodeNode node)
        {
            if (detail_expr == null)
            {
                return(get_signal_canonical_constant(sig));
            }

            if (detail_expr.value_type is NullType || !detail_expr.value_type.compatible(string_type))
            {
                node.error = true;
                Report.error(detail_expr.source_reference, "only string details are supported");
                return(null);
            }

            if (detail_expr is StringLiteral)
            {
                return(get_signal_canonical_constant(sig, ((StringLiteral)detail_expr).eval()));
            }

            var detail_value = create_temp_value(detail_expr.value_type, false, node, true);

            temp_ref_values.Insert(0, detail_value);

            var ccall = new CCodeFunctionCall(new CCodeIdentifier("g_strconcat"));

            ccall.add_argument(get_signal_canonical_constant(sig, ""));
            ccall.add_argument(get_cvalue(detail_expr));
            ccall.add_argument(new CCodeConstant("NULL"));

            ccode.add_assignment(get_cvalue_(detail_value), ccall);
            return(get_cvalue_(detail_value));
        }
示例#6
0
        public virtual void return_with_exception(CCodeExpression error_expr)
        {
            var cpropagate = new CCodeFunctionCall(new CCodeIdentifier("g_propagate_error"));

            cpropagate.add_argument(new CCodeIdentifier("error"));
            cpropagate.add_argument(error_expr);

            ccode.add_expression(cpropagate);

            // free local variables
            append_local_free(current_symbol, false);

            if (current_method is CreationMethod && current_method.parent_symbol is Class)
            {
                var cl = (Class)current_method.parent_symbol;
                ccode.add_expression(destroy_value(new GLibValue(new ObjectType(cl), new CCodeIdentifier("self"), true)));
                ccode.add_return(new CCodeConstant("NULL"));
            }
            else if (is_in_coroutine())
            {
                ccode.add_return(new CCodeConstant("FALSE"));
            }
            else
            {
                return_default_value(current_return_type);
            }
        }
示例#7
0
        CCodeExpression create_from_file_descriptor(DataType type, CCodeExpression expr)
        {
            if (type is ObjectType)
            {
                if (type.data_type.get_full_name() == "GLib.UnixInputStream")
                {
                    var result = new CCodeFunctionCall(new CCodeIdentifier("g_unix_input_stream_new"));
                    result.add_argument(expr);
                    result.add_argument(new CCodeConstant("TRUE"));
                    return(new CCodeCastExpression(result, "GUnixInputStream *"));
                }
                else if (type.data_type.get_full_name() == "GLib.UnixOutputStream")
                {
                    var result = new CCodeFunctionCall(new CCodeIdentifier("g_unix_output_stream_new"));
                    result.add_argument(expr);
                    result.add_argument(new CCodeConstant("TRUE"));
                    return(new CCodeCastExpression(result, "GUnixOutputStream *"));
                }
                else if (type.data_type.get_full_name() == "GLib.Socket")
                {
                    var result = new CCodeFunctionCall(new CCodeIdentifier("g_socket_new_from_fd"));
                    result.add_argument(expr);
                    result.add_argument(new CCodeConstant("NULL"));
                    return(result);
                }
            }

            return(null);
        }
示例#8
0
        CCodeExpression deserialize_array(ArrayType array_type, CCodeExpression variant_expr, CCodeExpression expr)
        {
            if (array_type.rank == 1 && get_type_signature(array_type) == "ay")
            {
                return(deserialize_buffer_array(array_type, variant_expr, expr));
            }

            string temp_name = "_tmp%d_".printf(next_temp_var_id++);

            var new_call = new CCodeFunctionCall(new CCodeIdentifier("g_new"));

            new_call.add_argument(new CCodeIdentifier(get_ccode_name(array_type.element_type)));
            // add one extra element for NULL-termination
            new_call.add_argument(new CCodeConstant("5"));

            ccode.add_declaration(get_ccode_name(array_type), new CCodeVariableDeclarator(temp_name, new_call));
            ccode.add_declaration("int", new CCodeVariableDeclarator(temp_name + "_length", new CCodeConstant("0")));
            ccode.add_declaration("int", new CCodeVariableDeclarator(temp_name + "_size", new CCodeConstant("4")));

            deserialize_array_dim(array_type, 1, temp_name, variant_expr, expr);

            if (array_type.element_type.is_reference_type_or_type_parameter())
            {
                // NULL terminate array
                var length         = new CCodeIdentifier(temp_name + "_length");
                var element_access = new CCodeElementAccess(new CCodeIdentifier(temp_name), length);
                ccode.add_assignment(element_access, new CCodeIdentifier("NULL"));
            }

            return(new CCodeIdentifier(temp_name));
        }
示例#9
0
        CCodeExpression deserialize_buffer_array(ArrayType array_type, CCodeExpression variant_expr, CCodeExpression expr)
        {
            string temp_name = "_tmp%d_".printf(next_temp_var_id++);

            var get_data_call = new CCodeFunctionCall(new CCodeIdentifier("g_variant_get_data"));

            get_data_call.add_argument(variant_expr);

            var get_size_call = new CCodeFunctionCall(new CCodeIdentifier("g_variant_get_size"));

            get_size_call.add_argument(variant_expr);
            ccode.add_declaration("gsize", new CCodeVariableDeclarator(temp_name + "_length", get_size_call));
            var length = new CCodeIdentifier(temp_name + "_length");

            var dup_call = new CCodeFunctionCall(new CCodeIdentifier("g_memdup"));

            dup_call.add_argument(get_data_call);
            dup_call.add_argument(length);

            ccode.add_declaration(get_ccode_name(array_type), new CCodeVariableDeclarator(temp_name, dup_call));
            if (expr != null)
            {
                ccode.add_assignment(get_array_length(expr, 1), length);
            }

            return(new CCodeIdentifier(temp_name));
        }
示例#10
0
        CCodeExpression get_array_length(CCodeExpression expr, int dim)
        {
            var id = expr as CCodeIdentifier;
            var ma = expr as CCodeMemberAccess;

            if (id != null)
            {
                return(new CCodeIdentifier("%s_length%d".printf(id.name, dim)));
            }
            else if (ma != null)
            {
                if (ma.is_pointer)
                {
                    return(CCodeMemberAccess.pointer(ma.inner, "%s_length%d".printf(ma.member_name, dim)));
                }
                else
                {
                    return(new CCodeMemberAccess(ma.inner, "%s_length%d".printf(ma.member_name, dim)));
                }
            }
            else
            {
                // must be NULL-terminated
                var len_call = new CCodeFunctionCall(new CCodeIdentifier("g_strv_length"));
                len_call.add_argument(expr);
                return(len_call);
            }
        }
示例#11
0
        public override void visit_catch_clause(CatchClause clause)
        {
            current_method_inner_error = true;

            var error_type = (ErrorType)clause.error_type;

            if (error_type.error_domain != null)
            {
                generate_error_domain_declaration(error_type.error_domain, cfile);
            }

            ccode.add_label(clause.clabel_name);

            ccode.open_block();

            if (clause.error_variable != null)
            {
                visit_local_variable(clause.error_variable);
                ccode.add_assignment(get_variable_cexpression(get_local_cname(clause.error_variable)), get_variable_cexpression("_inner_error_"));
            }
            else
            {
                // error object is not used within catch statement, clear it
                var cclear = new CCodeFunctionCall(new CCodeIdentifier("g_clear_error"));
                cclear.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, get_variable_cexpression("_inner_error_")));
                ccode.add_expression(cclear);
            }
            ccode.add_assignment(get_variable_cexpression("_inner_error_"), new CCodeConstant("NULL"));

            clause.body.emit(this);

            ccode.close();
        }
示例#12
0
        public override void get_type_interface_init_statements(CCodeBlock block, bool plugin)
        {
            foreach (DataType base_type in class_reference.get_base_types())
            {
                if (!(base_type.data_type is Interface))
                {
                    continue;
                }

                var iface = (Interface)base_type.data_type;

                var iface_info_name = "%s_info".printf(CCodeBaseModule.get_ccode_lower_case_name(iface, null));
                if (!plugin)
                {
                    var reg_call = new CCodeFunctionCall(new CCodeIdentifier("g_type_add_interface_static"));
                    reg_call.add_argument(new CCodeIdentifier("%s_type_id".printf(CCodeBaseModule.get_ccode_lower_case_name(class_reference, null))));
                    reg_call.add_argument(new CCodeIdentifier(CCodeBaseModule.get_ccode_type_id(iface)));
                    reg_call.add_argument(new CCodeIdentifier("&%s".printf(iface_info_name)));
                    block.add_statement(new CCodeExpressionStatement(reg_call));
                }
                else
                {
                    var reg_call = new CCodeFunctionCall(new CCodeIdentifier("g_type_module_add_interface"));
                    reg_call.add_argument(new CCodeIdentifier("module"));
                    reg_call.add_argument(new CCodeIdentifier("%s_type_id".printf(CCodeBaseModule.get_ccode_lower_case_name(class_reference, null))));
                    reg_call.add_argument(new CCodeIdentifier(CCodeBaseModule.get_ccode_type_id(iface)));
                    reg_call.add_argument(new CCodeIdentifier("&%s".printf(iface_info_name)));
                    block.add_statement(new CCodeExpressionStatement(reg_call));
                }
            }

            ((CCodeBaseModule)context.codegen).register_dbus_info(block, class_reference);
        }
示例#13
0
        void add_struct_free_function(Struct st)
        {
            var function = new CCodeFunction(get_ccode_free_function(st), "void");

            if (st.is_private_symbol())
            {
                function.modifiers = CCodeModifiers.STATIC;
            }
            else if (context.hide_internal && st.is_internal_symbol())
            {
                function.modifiers = CCodeModifiers.INTERNAL;
            }

            function.add_parameter(new CCodeParameter("self", get_ccode_name(st) + "*"));

            push_function(function);

            if (st.is_disposable())
            {
                var destroy_call = new CCodeFunctionCall(new CCodeIdentifier(get_ccode_destroy_function(st)));
                destroy_call.add_argument(new CCodeIdentifier("self"));
                ccode.add_expression(destroy_call);
            }

            var free_call = new CCodeFunctionCall(new CCodeIdentifier("g_free"));

            free_call.add_argument(new CCodeIdentifier("self"));
            ccode.add_expression(free_call);

            pop_function();

            cfile.add_function(function);
        }
示例#14
0
        public override CCodeExpression destroy_value(TargetValue value, bool is_macro_definition = false)
        {
            var type = value.value_type;

            if (type is ArrayType)
            {
                var array_type = (ArrayType)type;

                if (!array_type.fixed_length)
                {
                    return(base.destroy_value(value, is_macro_definition));
                }

                requires_array_free = true;

                var ccall = new CCodeFunctionCall(get_destroy_func_expression(type));

                ccall = new CCodeFunctionCall(new CCodeIdentifier("_vala_array_destroy"));
                ccall.add_argument(get_cvalue_(value));
                ccall.add_argument(get_ccodenode(array_type.length));
                ccall.add_argument(new CCodeCastExpression(get_destroy_func_expression(array_type.element_type), "GDestroyNotify"));

                return(ccall);
            }
            else
            {
                return(base.destroy_value(value, is_macro_definition));
            }
        }
示例#15
0
        public override TargetValue copy_value(TargetValue value, CodeNode node)
        {
            var type  = value.value_type;
            var cexpr = get_cvalue_(value);

            if (type is ArrayType)
            {
                var array_type = (ArrayType)type;

                if (!array_type.fixed_length)
                {
                    return(base.copy_value(value, node));
                }

                var temp_value = create_temp_value(type, false, node);

                var copy_call = new CCodeFunctionCall(new CCodeIdentifier(generate_array_copy_wrapper(array_type)));
                copy_call.add_argument(cexpr);
                copy_call.add_argument(get_cvalue_(temp_value));
                ccode.add_expression(copy_call);

                return(temp_value);
            }
            else
            {
                return(base.copy_value(value, node));
            }
        }
示例#16
0
        CCodeExpression serialize_buffer_array(ArrayType array_type, CCodeExpression array_expr)
        {
            string buffer_name = "_tmp%d_".printf(next_temp_var_id++);

            var gvariant_type = new CCodeFunctionCall(new CCodeIdentifier("G_VARIANT_TYPE"));

            gvariant_type.add_argument(new CCodeConstant("\"%s\"".printf(get_type_signature(array_type))));

            var dup_call = new CCodeFunctionCall(new CCodeIdentifier("g_memdup"));

            dup_call.add_argument(array_expr);
            dup_call.add_argument(get_array_length(array_expr, 1));
            ccode.add_declaration(get_ccode_name(array_type), new CCodeVariableDeclarator(buffer_name, dup_call));

            var new_call = new CCodeFunctionCall(new CCodeIdentifier("g_variant_new_from_data"));

            new_call.add_argument(gvariant_type);
            new_call.add_argument(new CCodeIdentifier(buffer_name));
            new_call.add_argument(get_array_length(array_expr, 1));
            new_call.add_argument(new CCodeConstant("TRUE"));
            new_call.add_argument(new CCodeIdentifier("g_free"));
            new_call.add_argument(new CCodeIdentifier(buffer_name));

            return(new_call);
        }
示例#17
0
        CCodeExpression serialize_basic(BasicTypeInfo basic_type, CCodeExpression expr)
        {
            var new_call = new CCodeFunctionCall(new CCodeIdentifier("g_variant_new_" + basic_type.type_name));

            new_call.add_argument(expr);
            return(new_call);
        }
示例#18
0
        string generate_array_copy_wrapper(ArrayType array_type)
        {
            string dup_func = "_vala_array_copy%d".printf(++next_array_dup_id);

            if (!add_wrapper(dup_func))
            {
                // wrapper already defined
                return(dup_func);
            }

            // declaration

            var function = new CCodeFunction(dup_func, "void");

            function.modifiers = CCodeModifiers.STATIC;

            function.add_parameter(new CCodeParameter("self", "%s *".printf(get_ccode_name(array_type))));
            function.add_parameter(new CCodeParameter("dest", "%s *".printf(get_ccode_name(array_type))));

            // definition

            push_context(new EmitContext());
            push_function(function);

            if (requires_copy(array_type.element_type))
            {
                ccode.add_declaration("int", new CCodeVariableDeclarator("i"));

                ccode.open_for(new CCodeAssignment(new CCodeIdentifier("i"), new CCodeConstant("0")),
                               new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier("i"), get_ccodenode(array_type.length)),
                               new CCodeUnaryExpression(CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier("i")));


                ccode.add_assignment(new CCodeElementAccess(new CCodeIdentifier("dest"), new CCodeIdentifier("i")), get_cvalue_(copy_value(new GLibValue(array_type.element_type, new CCodeElementAccess(new CCodeIdentifier("self"), new CCodeIdentifier("i")), true), array_type)));
            }
            else
            {
                cfile.add_include("string.h");

                var dup_call = new CCodeFunctionCall(new CCodeIdentifier("memcpy"));
                dup_call.add_argument(new CCodeIdentifier("dest"));
                dup_call.add_argument(new CCodeIdentifier("self"));

                var sizeof_call = new CCodeFunctionCall(new CCodeIdentifier("sizeof"));
                sizeof_call.add_argument(new CCodeIdentifier(get_ccode_name(array_type.element_type)));
                dup_call.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.MUL, get_ccodenode(array_type.length), sizeof_call));

                ccode.add_expression(dup_call);
            }

            // append to file

            cfile.add_function_declaration(function);
            cfile.add_function(function);

            pop_context();

            return(dup_func);
        }
示例#19
0
        public override void visit_method_call(MethodCall expr)
        {
            if (expr.call is MemberAccess)
            {
                push_line(expr.source_reference);

                var ma = expr.call as MemberAccess;
                if (ma.inner != null && ma.inner.symbol_reference == gobject_type &&
                    (ma.member_name == "new" || ma.member_name == "newv"))
                {
                    // Object.new (...) creation
                    // runtime check to ref_sink the instance if it's a floating type
                    base.visit_method_call(expr);

                    var initiallyunowned_ccall = new CCodeFunctionCall(new CCodeIdentifier("G_IS_INITIALLY_UNOWNED"));
                    initiallyunowned_ccall.add_argument(get_cvalue(expr));
                    var sink_ref_ccall = new CCodeFunctionCall(new CCodeIdentifier("g_object_ref_sink"));
                    sink_ref_ccall.add_argument(get_cvalue(expr));
                    var cexpr = new CCodeConditionalExpression(initiallyunowned_ccall, sink_ref_ccall, get_cvalue(expr));

                    expr.target_value = store_temp_value(new GLibValue(expr.value_type, cexpr), expr);
                    return;
                }
                else if (ma.symbol_reference == gobject_type)
                {
                    // Object (...) chain up
                    // check it's only used with valid properties
                    foreach (var arg in expr.get_argument_list())
                    {
                        var named_argument = arg as NamedArgument;
                        if (named_argument == null)
                        {
                            Report.error(arg.source_reference, "Named argument expected");
                            break;
                        }
                        var prop = SemanticAnalyzer.symbol_lookup_inherited(current_class, named_argument.name) as Property;
                        if (prop == null)
                        {
                            Report.error(arg.source_reference, "Property `%s' not found in `%s'".printf(named_argument.name, current_class.get_full_name()));
                            break;
                        }
                        if (!is_gobject_property(prop))
                        {
                            Report.error(arg.source_reference, "Property `%s' not supported in Object (property: value) constructor chain up".printf(named_argument.name));
                            break;
                        }
                        if (!arg.value_type.compatible(prop.property_type))
                        {
                            Report.error(arg.source_reference, "Cannot convert from `%s' to `%s'".printf(arg.value_type.ToString(), prop.property_type.ToString()));
                            break;
                        }
                    }
                }

                pop_line();
            }

            base.visit_method_call(expr);
        }
示例#20
0
        public override CCodeExpression deserialize_expression(DataType type, CCodeExpression variant_expr, CCodeExpression expr, out bool may_fail, CCodeExpression error_expr = null)
        {
            BasicTypeInfo   basic_type;
            CCodeExpression result = null;

            may_fail = false;
            if (is_string_marshalled_enum(type.data_type))
            {
                get_basic_type_info("s", out basic_type);
                result   = deserialize_basic(basic_type, variant_expr, true);
                result   = generate_enum_value_from_string(type as EnumValueType, result, error_expr);
                may_fail = true;
            }
            else if (get_basic_type_info(get_type_signature(type), out basic_type))
            {
                result = deserialize_basic(basic_type, variant_expr);
            }
            else if (type is ArrayType)
            {
                result = deserialize_array((ArrayType)type, variant_expr, expr);
            }
            else if (type.data_type is Struct)
            {
                var st = (Struct)type.data_type;
                result = deserialize_struct(st, variant_expr);
                if (result != null && type.nullable)
                {
                    var csizeof = new CCodeFunctionCall(new CCodeIdentifier("sizeof"));
                    csizeof.add_argument(new CCodeIdentifier(get_ccode_name(st)));
                    var cdup = new CCodeFunctionCall(new CCodeIdentifier("g_memdup"));
                    cdup.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, result));
                    cdup.add_argument(csizeof);
                    result = cdup;
                }
            }
            else if (type is ObjectType)
            {
                if (type.data_type.get_full_name() == "GLib.Variant")
                {
                    var variant_get = new CCodeFunctionCall(new CCodeIdentifier("g_variant_get_variant"));
                    variant_get.add_argument(variant_expr);
                    result = variant_get;
                }
                else if (type.data_type.get_full_name() == "GLib.HashTable")
                {
                    result = deserialize_hash_table((ObjectType)type, variant_expr);
                }
            }

            if (result == null)
            {
                Report.error(type.source_reference, "GVariant deserialization of type `%s' is not supported".printf(type.ToString()));
            }

            return(result);
        }
示例#21
0
        public override void append_vala_array_free()
        {
            // _vala_array_destroy only frees elements but not the array itself

            var fun = new CCodeFunction("_vala_array_destroy", "void");

            fun.modifiers = CCodeModifiers.STATIC;
            fun.add_parameter(new CCodeParameter("array", "gpointer"));
            fun.add_parameter(new CCodeParameter("array_length", "gint"));
            fun.add_parameter(new CCodeParameter("destroy_func", "GDestroyNotify"));

            push_function(fun);

            var ccondarr  = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier("array"), new CCodeConstant("NULL"));
            var ccondfunc = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, new CCodeIdentifier("destroy_func"), new CCodeConstant("NULL"));

            ccode.open_if(new CCodeBinaryExpression(CCodeBinaryOperator.AND, ccondarr, ccondfunc));

            ccode.add_declaration("int", new CCodeVariableDeclarator("i"));
            append_vala_array_free_loop();

            ccode.close();

            pop_function();

            cfile.add_function_declaration(fun);
            cfile.add_function(fun);

            // _vala_array_free frees elements and array

            fun           = new CCodeFunction("_vala_array_free", "void");
            fun.modifiers = CCodeModifiers.STATIC;
            fun.add_parameter(new CCodeParameter("array", "gpointer"));
            fun.add_parameter(new CCodeParameter("array_length", "gint"));
            fun.add_parameter(new CCodeParameter("destroy_func", "GDestroyNotify"));

            push_function(fun);

            // call _vala_array_destroy to free the array elements
            var ccall = new CCodeFunctionCall(new CCodeIdentifier("_vala_array_destroy"));

            ccall.add_argument(new CCodeIdentifier("array"));
            ccall.add_argument(new CCodeIdentifier("array_length"));
            ccall.add_argument(new CCodeIdentifier("destroy_func"));
            ccode.add_expression(ccall);

            var carrfree = new CCodeFunctionCall(new CCodeIdentifier("g_free"));

            carrfree.add_argument(new CCodeIdentifier("array"));
            ccode.add_expression(carrfree);

            pop_function();

            cfile.add_function_declaration(fun);
            cfile.add_function(fun);
        }
示例#22
0
        private void emit_invalid_property_id_warn()
        {
            // warn on invalid property id
            var cwarn = new CCodeFunctionCall(new CCodeIdentifier("G_OBJECT_WARN_INVALID_PROPERTY_ID"));

            cwarn.add_argument(new CCodeIdentifier("object"));
            cwarn.add_argument(new CCodeIdentifier("property_id"));
            cwarn.add_argument(new CCodeIdentifier("pspec"));
            ccode.add_expression(cwarn);
        }
示例#23
0
        CCodeExpression serialize_array_dim(ArrayType array_type, int dim, CCodeExpression array_expr, CCodeExpression array_iter_expr)
        {
            string builder_name = "_tmp%d_".printf(next_temp_var_id++);
            string index_name   = "_tmp%d_".printf(next_temp_var_id++);

            ccode.add_declaration("GVariantBuilder", new CCodeVariableDeclarator(builder_name));
            ccode.add_declaration("int", new CCodeVariableDeclarator(index_name));

            var gvariant_type = new CCodeFunctionCall(new CCodeIdentifier("G_VARIANT_TYPE"));

            gvariant_type.add_argument(new CCodeConstant("\"%s\"".printf(get_type_signature(array_type))));

            var builder_init = new CCodeFunctionCall(new CCodeIdentifier("g_variant_builder_init"));

            builder_init.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier(builder_name)));
            builder_init.add_argument(gvariant_type);
            ccode.add_expression(builder_init);

            var cforinit = new CCodeAssignment(new CCodeIdentifier(index_name), new CCodeConstant("0"));
            var cforcond = new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier(index_name), get_array_length(array_expr, dim));
            var cforiter = new CCodeUnaryExpression(CCodeUnaryOperator.POSTFIX_INCREMENT, new CCodeIdentifier(index_name));

            ccode.open_for(cforinit, cforcond, cforiter);

            CCodeExpression element_variant;

            if (dim < array_type.rank)
            {
                element_variant = serialize_array_dim(array_type, dim + 1, array_expr, array_iter_expr);
            }
            else
            {
                var element_expr = new CCodeUnaryExpression(CCodeUnaryOperator.POINTER_INDIRECTION, array_iter_expr);
                element_variant = serialize_expression(array_type.element_type, element_expr);
            }

            var builder_add = new CCodeFunctionCall(new CCodeIdentifier("g_variant_builder_add_value"));

            builder_add.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier(builder_name)));
            builder_add.add_argument(element_variant);
            ccode.add_expression(builder_add);

            if (dim == array_type.rank)
            {
                var array_iter_incr = new CCodeUnaryExpression(CCodeUnaryOperator.POSTFIX_INCREMENT, array_iter_expr);
                ccode.add_expression(array_iter_incr);
            }

            ccode.close();

            var builder_end = new CCodeFunctionCall(new CCodeIdentifier("g_variant_builder_end"));

            builder_end.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier(builder_name)));
            return(builder_end);
        }
示例#24
0
        CCodeExpression generate_enum_value_to_string(EnumValueType type, CCodeExpression expr)
        {
            var en             = type.type_symbol as ValaEnum;
            var to_string_name = "%s_to_string".printf(get_ccode_lower_case_name(en, null));

            var to_string_call = new CCodeFunctionCall(new CCodeIdentifier(to_string_name));

            to_string_call.add_argument(expr);

            return(to_string_call);
        }
示例#25
0
        CCodeExpression generate_enum_value_from_string(EnumValueType type, CCodeExpression expr, CCodeExpression error_expr)
        {
            var en = type.type_symbol as ValaEnum;
            var from_string_name = "%s_from_string".printf(get_ccode_lower_case_name(en, null));

            var from_string_call = new CCodeFunctionCall(new CCodeIdentifier(from_string_name));

            from_string_call.add_argument(expr);
            from_string_call.add_argument(error_expr != null ? error_expr : new CCodeConstant("NULL"));

            return(from_string_call);
        }
示例#26
0
        void uncaught_error_statement(CCodeExpression inner_error, bool unexpected = false)
        {
            // free local variables
            append_local_free(current_symbol, false);

            var ccritical = new CCodeFunctionCall(new CCodeIdentifier("g_critical"));

            ccritical.add_argument(new CCodeConstant(unexpected ? "\"file %s: line %d: unexpected error: %s (%s, %d)\"" : "\"file %s: line %d: uncaught error: %s (%s, %d)\""));
            ccritical.add_argument(new CCodeConstant("__FILE__"));
            ccritical.add_argument(new CCodeConstant("__LINE__"));
            ccritical.add_argument(CCodeMemberAccess.pointer(inner_error, "message"));
            var domain_name = new CCodeFunctionCall(new CCodeIdentifier("g_quark_to_string"));

            domain_name.add_argument(CCodeMemberAccess.pointer(inner_error, "domain"));
            ccritical.add_argument(domain_name);
            ccritical.add_argument(CCodeMemberAccess.pointer(inner_error, "code"));

            var cclear = new CCodeFunctionCall(new CCodeIdentifier("g_clear_error"));

            cclear.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, inner_error));

            // print critical message
            ccode.add_expression(ccritical);
            ccode.add_expression(cclear);

            if (is_in_constructor() || is_in_destructor())
            {
                // just print critical, do not return prematurely
            }
            else if (current_method is CreationMethod)
            {
                if (current_method.parent_symbol is Struct)
                {
                    ccode.add_return();
                }
                else
                {
                    ccode.add_return(new CCodeConstant("NULL"));
                }
            }
            else if (is_in_coroutine())
            {
                var async_result_expr = CCodeMemberAccess.pointer(new CCodeIdentifier("_data_"), "_async_result");
                var unref             = new CCodeFunctionCall(new CCodeIdentifier("g_object_unref"));
                unref.add_argument(async_result_expr);
                ccode.add_expression(unref);
                ccode.add_return(new CCodeConstant("FALSE"));
            }
            else if (current_return_type != null)
            {
                return_default_value(current_return_type);
            }
        }
示例#27
0
        public void receive_dbus_value(DataType type, CCodeExpression message_expr, CCodeExpression iter_expr, CCodeExpression target_expr, Symbol sym, out bool may_fail, CCodeExpression error_expr = null)
        {
            may_fail = true;

            var fd_list = new CCodeFunctionCall(new CCodeIdentifier("g_dbus_message_get_unix_fd_list"));

            fd_list.add_argument(message_expr);

            var fd_var = new CCodeIdentifier("_fd");

            var stream = create_from_file_descriptor(type, fd_var);

            if (stream != null)
            {
                var fd_list_var = new CCodeIdentifier("_fd_list");

                var fd = new CCodeFunctionCall(new CCodeIdentifier("g_unix_fd_list_get"));
                fd.add_argument(fd_list_var);
                fd.add_argument(new CCodeIdentifier("_fd_index"));
                fd.add_argument(error_expr);

                ccode.add_assignment(fd_list_var, fd_list);
                ccode.open_if(fd_list_var);

                var get_fd = new CCodeFunctionCall(new CCodeIdentifier("g_variant_iter_next"));
                get_fd.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, iter_expr));
                get_fd.add_argument(new CCodeConstant("\"h\""));
                get_fd.add_argument(new CCodeUnaryExpression(CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier("_fd_index")));
                ccode.add_expression(get_fd);

                ccode.add_assignment(fd_var, fd);
                ccode.open_if(new CCodeBinaryExpression(CCodeBinaryOperator.GREATER_THAN_OR_EQUAL, fd_var, new CCodeConstant("0")));

                ccode.add_assignment(target_expr, stream);
                may_fail = true;

                ccode.close();

                ccode.add_else();
                var set_error = new CCodeFunctionCall(new CCodeIdentifier("g_set_error_literal"));
                set_error.add_argument(error_expr);
                set_error.add_argument(new CCodeIdentifier("G_IO_ERROR"));
                set_error.add_argument(new CCodeIdentifier("G_IO_ERROR_FAILED"));
                set_error.add_argument(new CCodeConstant("\"FD List is NULL\""));
                ccode.add_expression(set_error);
                ccode.close();
            }
            else
            {
                read_expression(type, iter_expr, target_expr, sym, out may_fail, error_expr);
            }
        }
示例#28
0
        public override void visit_method(Method m)
        {
            base.visit_method(m);

            var cl = current_class;

            if (cl == null || cl.error || !is_gtk_template(cl))
            {
                return;
            }

            if (m.binding != MemberBinding.INSTANCE || m.get_attribute("GtkCallback") == null)
            {
                return;
            }

            /* Handler name as defined in the gtkbuilder xml */
            var handler_name = m.get_attribute_string("GtkCallback", "name", m.name);
            var sig          = current_handler_to_signal_map[handler_name];

            if (sig == null)
            {
                Report.error(m.source_reference, "could not find signal for handler `%s'".printf(handler_name));
                return;
            }

            push_context(class_init_context);

            if (sig != null)
            {
                sig.check(context);
                var method_type   = new MethodType(m);
                var signal_type   = new SignalType(sig);
                var delegate_type = signal_type.get_handler_type();
                if (!method_type.compatible(delegate_type))
                {
                    Report.error(m.source_reference, "method `%s' is incompatible with signal `%s', expected `%s'".printf(method_type.ToString(), delegate_type.ToString(), delegate_type.delegate_symbol.get_prototype_string(m.name)));
                }
                else
                {
                    var wrapper = generate_delegate_wrapper(m, signal_type.get_handler_type(), m);

                    var call = new CCodeFunctionCall(new CCodeIdentifier("gtk_widget_class_bind_template_callback_full"));
                    call.add_argument(new CCodeIdentifier("GTK_WIDGET_CLASS (klass)"));
                    call.add_argument(new CCodeConstant("\"%s\"".printf(handler_name)));
                    call.add_argument(new CCodeIdentifier("G_CALLBACK(%s)".printf(wrapper)));
                    ccode.add_expression(call);
                }
            }

            pop_context();
        }
示例#29
0
        public override void visit_element_access(ElementAccess expr)
        {
            if (expr.container is MemberAccess && expr.container.symbol_reference is Signal)
            {
                if (expr.parent_node is MethodCall)
                {
                    // detailed signal emission
                    var sig = (Signal)expr.symbol_reference;
                    var ma  = (MemberAccess)expr.container;

                    var detail_expr = expr.get_indices()[0];

                    CCodeFunctionCall ccall;
                    if (!sig.external_package && expr.source_reference.file == sig.source_reference.file)
                    {
                        var detail_cexpr = get_detail_cexpression(detail_expr, expr);

                        ccall = new CCodeFunctionCall(new CCodeIdentifier("g_signal_emit"));
                        ccall.add_argument(get_cvalue(ma.inner));
                        ccall.add_argument(get_signal_id_cexpression(sig));
                        if (detail_cexpr != null)
                        {
                            ccall.add_argument(detail_cexpr);
                        }
                    }
                    else
                    {
                        var signal_name_cexpr = get_signal_name_cexpression(sig, detail_expr, expr);

                        ccall = new CCodeFunctionCall(new CCodeIdentifier("g_signal_emit_by_name"));
                        ccall.add_argument(get_cvalue(ma.inner));
                        if (signal_name_cexpr != null)
                        {
                            ccall.add_argument(signal_name_cexpr);
                        }
                    }

                    set_cvalue(expr, ccall);
                }
                else
                {
                    // signal connect or disconnect
                }
            }
            else
            {
                base.visit_element_access(expr);
            }
        }
示例#30
0
        public override CCodeExpression serialize_expression(DataType type, CCodeExpression expr)
        {
            BasicTypeInfo   basic_type;
            CCodeExpression result = null;

            if (is_string_marshalled_enum(type.data_type))
            {
                get_basic_type_info("s", out basic_type);
                result = generate_enum_value_to_string(type as EnumValueType, expr);
                result = serialize_basic(basic_type, result);
            }
            else if (get_basic_type_info(get_type_signature(type), out basic_type))
            {
                result = serialize_basic(basic_type, expr);
            }
            else if (type is ArrayType)
            {
                result = serialize_array((ArrayType)type, expr);
            }
            else if (type.data_type is Struct)
            {
                var st_expr = expr;
                if (type.nullable)
                {
                    st_expr = new CCodeUnaryExpression(CCodeUnaryOperator.POINTER_INDIRECTION, st_expr);
                }
                result = serialize_struct((Struct)type.data_type, st_expr);
            }
            else if (type is ObjectType)
            {
                if (type.data_type.get_full_name() == "GLib.Variant")
                {
                    var variant_new = new CCodeFunctionCall(new CCodeIdentifier("g_variant_new_variant"));
                    variant_new.add_argument(expr);
                    result = variant_new;
                }
                else if (type.data_type.get_full_name() == "GLib.HashTable")
                {
                    result = serialize_hash_table((ObjectType)type, expr);
                }
            }

            if (result == null)
            {
                Report.error(type.source_reference, "GVariant serialization of type `%s' is not supported".printf(type.ToString()));
            }

            return(result);
        }