Exemplo n.º 1
0
        void append_vala_array_free_loop()
        {
            var cforinit = new CCodeAssignment(new CCodeIdentifier("i"), new CCodeConstant("0"));
            var cforcond = new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, new CCodeIdentifier("i"), new CCodeIdentifier("array_length"));
            var cforiter = new CCodeAssignment(new CCodeIdentifier("i"), new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, new CCodeIdentifier("i"), new CCodeConstant("1")));

            ccode.open_for(cforinit, cforcond, cforiter);

            var cptrarray = new CCodeCastExpression(new CCodeIdentifier("array"), "gpointer*");
            var cea       = new CCodeElementAccess(cptrarray, new CCodeIdentifier("i"));

            var cfreecond = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, cea, new CCodeConstant("NULL"));

            ccode.open_if(cfreecond);

            var cfreecall = new CCodeFunctionCall(new CCodeIdentifier("destroy_func"));

            cfreecall.add_argument(cea);
            ccode.add_expression(cfreecall);

            ccode.close();
        }
Exemplo n.º 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);
        }
Exemplo n.º 3
0
        public override void append_vala_array_move()
        {
            cfile.add_include("string.h");

            // assumes that overwritten array elements are null before invocation
            // FIXME will leak memory if that's not the case
            var fun = new CCodeFunction("_vala_array_move", "void");

            fun.modifiers = CCodeModifiers.STATIC;
            fun.add_parameter(new CCodeParameter("array", "gpointer"));
            fun.add_parameter(new CCodeParameter("element_size", "gsize"));
            fun.add_parameter(new CCodeParameter("src", "gint"));
            fun.add_parameter(new CCodeParameter("dest", "gint"));
            fun.add_parameter(new CCodeParameter("length", "gint"));

            push_function(fun);

            var array            = new CCodeCastExpression(new CCodeIdentifier("array"), "char*");
            var element_size     = new CCodeIdentifier("element_size");
            var length           = new CCodeIdentifier("length");
            var src              = new CCodeIdentifier("src");
            var src_end          = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, src, length);
            var dest             = new CCodeIdentifier("dest");
            var dest_end         = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, dest, length);
            var src_address      = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression(CCodeBinaryOperator.MUL, src, element_size));
            var dest_address     = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression(CCodeBinaryOperator.MUL, dest, element_size));
            var dest_end_address = new CCodeBinaryExpression(CCodeBinaryOperator.PLUS, array, new CCodeBinaryExpression(CCodeBinaryOperator.MUL, dest_end, element_size));

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

            ccall.add_argument(dest_address);
            ccall.add_argument(src_address);
            ccall.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.MUL, length, element_size));
            ccode.add_expression(ccall);

            ccode.open_if(new CCodeBinaryExpression(CCodeBinaryOperator.AND, new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, src, dest), new CCodeBinaryExpression(CCodeBinaryOperator.GREATER_THAN, src_end, dest)));

            var czero1 = new CCodeFunctionCall(new CCodeIdentifier("memset"));

            czero1.add_argument(src_address);
            czero1.add_argument(new CCodeConstant("0"));
            czero1.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.MUL, new CCodeBinaryExpression(CCodeBinaryOperator.MINUS, dest, src), element_size));
            ccode.add_expression(czero1);

            ccode.else_if(new CCodeBinaryExpression(CCodeBinaryOperator.AND, new CCodeBinaryExpression(CCodeBinaryOperator.GREATER_THAN, src, dest), new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, src, dest_end)));

            var czero2 = new CCodeFunctionCall(new CCodeIdentifier("memset"));

            czero2.add_argument(dest_end_address);
            czero2.add_argument(new CCodeConstant("0"));
            czero2.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.MUL, new CCodeBinaryExpression(CCodeBinaryOperator.MINUS, src, dest), element_size));
            ccode.add_expression(czero2);

            ccode.else_if(new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, src, dest));

            var czero3 = new CCodeFunctionCall(new CCodeIdentifier("memset"));

            czero3.add_argument(src_address);
            czero3.add_argument(new CCodeConstant("0"));
            czero3.add_argument(new CCodeBinaryExpression(CCodeBinaryOperator.MUL, length, element_size));
            ccode.add_expression(czero3);

            ccode.close();

            pop_function();

            cfile.add_function_declaration(fun);
            cfile.add_function(fun);
        }
Exemplo n.º 4
0
		public override void store_value(TargetValue lvalue, TargetValue value, SourceReference source_reference = null) {
			var array_type = lvalue.value_type as ArrayType;

			if (array_type != null && array_type.fixed_length) {
				cfile.add_include("string.h");

				// it is necessary to use memcpy for fixed-length (stack-allocated) arrays
				// simple assignments do not work in C
				var sizeof_call = new CCodeFunctionCall(new CCodeIdentifier("sizeof"));
				sizeof_call.add_argument(new CCodeIdentifier(get_ccode_name(array_type.element_type)));
				var size = new CCodeBinaryExpression(CCodeBinaryOperator.MUL, get_ccodenode(array_type.length), sizeof_call);

				var ccopy = new CCodeFunctionCall(new CCodeIdentifier("memcpy"));
				ccopy.add_argument(get_cvalue_(lvalue));
				ccopy.add_argument(get_cvalue_(value));
				ccopy.add_argument(size);
				ccode.add_expression(ccopy);

				return;
			}

			var cexpr = get_cvalue_(value);
			if (get_ctype(lvalue) != null) {
				cexpr = new CCodeCastExpression(cexpr, get_ctype(lvalue));
			}

			/*
			 * If this is a SimpleType struct being passed by value
			 * and the user specified a custom user function
			 * use the specified function instead to do assignments rather than dest = source
			 */
			var st_left = lvalue.value_type.data_type as Struct;
			var st_right = value.value_type.data_type as Struct;
			if (
				st_left != null &&
				st_right != null &&
				lvalue.value_type.compatible(value.value_type) &&
				st_left.is_simple_type() &&
				lvalue.value_type is StructValueType &&
				st_left.has_attribute_argument("CCode", "copy_function")
			) {
				//copy_function (src, dest)
				var copy_call = new CCodeFunctionCall(new CCodeIdentifier(get_ccode_copy_function(st_left)));
				copy_call.add_argument(get_cvalue_(value));
				copy_call.add_argument(get_cvalue_(lvalue));
				ccode.add_expression(copy_call);
				return;
			}

			ccode.add_assignment(get_cvalue_(lvalue), cexpr);

			if (array_type != null && ((GLibValue)lvalue).array_length_cvalues != null) {
				var glib_value = (GLibValue)value;
				if (glib_value.array_length_cvalues != null) {
					for (int dim = 1; dim <= array_type.rank; dim++) {
						ccode.add_assignment(get_array_length_cvalue(lvalue, dim), get_array_length_cvalue(value, dim));
					}
				} else if (glib_value.array_null_terminated) {
					requires_array_length = true;
					var len_call = new CCodeFunctionCall(new CCodeIdentifier("_vala_array_length"));
					len_call.add_argument(get_cvalue_(value));

					ccode.add_assignment(get_array_length_cvalue(lvalue, 1), len_call);
				} else {
					for (int dim = 1; dim <= array_type.rank; dim++) {
						ccode.add_assignment(get_array_length_cvalue(lvalue, dim), new CCodeConstant("-1"));
					}
				}

				if (array_type.rank == 1 && get_array_size_cvalue(lvalue) != null) {
					ccode.add_assignment(get_array_size_cvalue(lvalue), get_array_length_cvalue(lvalue, 1));
				}
			}

			var delegate_type = lvalue.value_type as DelegateType;
			if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
				var lvalue_target = get_delegate_target_cvalue(lvalue);
				var rvalue_target = get_delegate_target_cvalue(value);
				if (lvalue_target != null) {
					if (rvalue_target != null) {
						ccode.add_assignment(lvalue_target, rvalue_target);
					} else {
						Report.error(source_reference, "Assigning delegate without required target in scope");
						ccode.add_assignment(lvalue_target, new CCodeInvalidExpression());
					}
					var lvalue_destroy_notify = get_delegate_target_destroy_notify_cvalue(lvalue);
					var rvalue_destroy_notify = get_delegate_target_destroy_notify_cvalue(value);
					if (lvalue_destroy_notify != null) {
						if (rvalue_destroy_notify != null) {
							ccode.add_assignment(lvalue_destroy_notify, rvalue_destroy_notify);
						} else {
							ccode.add_assignment(lvalue_destroy_notify, new CCodeConstant("NULL"));
						}
					}
				}
			}
		}