2007-07-27 Jürg Billeter <j@bitron.ch>
+ * vala/Makefile.am, vala/valaarray.vala, vala/valaarraymovemethod.vala,
+ vala/valadatatype.vala, vala/valatypeparameter.vala,
+ gobject/valacodegenerator.vala,
+ gobject/valacodegeneratorinvocationexpression.vala,
+ gobject/valacodegeneratorsourcefile.vala: add move method to arrays
+
+2007-07-27 Jürg Billeter <j@bitron.ch>
+
* vala/valasemanticanalyzer.vala: fix warning when connecting signals
2007-07-27 Jürg Billeter <j@bitron.ch>
private bool string_h_needed;
private bool requires_free_checked;
private bool requires_array_free;
+ private bool requires_array_move;
public CodeGenerator (bool manage_memory = true) {
memory_management = manage_memory;
if (m is ArrayResizeMethod) {
var array = (Array) m.parent_symbol;
ccall.add_argument (new CCodeIdentifier (array.get_cname ()));
+ } else if (m is ArrayMoveMethod) {
+ requires_array_move = true;
}
/* explicitly use strong reference as ccall gets unrefed
ccall.add_argument (instance);
}
}
-
+
+ if (m is ArrayMoveMethod) {
+ var array = (Array) m.parent_symbol;
+ var csizeof = new CCodeFunctionCall (new CCodeIdentifier ("sizeof"));
+ csizeof.add_argument (new CCodeIdentifier (array.get_cname ()));
+ ccall.add_argument (csizeof);
+ }
+
bool ellipsis = false;
var i = 1;
string_h_needed = false;
requires_free_checked = false;
requires_array_free = false;
+ requires_array_move = false;
header_begin.append (new CCodeIncludeDirective ("glib.h"));
header_begin.append (new CCodeIncludeDirective ("glib-object.h"));
var header_define = get_define_for_filename (source_file.get_cheader_filename ());
- if (string_h_needed) {
- source_include_directives.append (new CCodeIncludeDirective ("string.h"));
- }
-
/* generate hardcoded "well-known" macros */
if (requires_free_checked) {
source_begin.append (new CCodeMacroReplacement ("VALA_FREE_CHECKED(o,f)", "((o) == NULL ? NULL : ((o) = (f (o), NULL)))"));
source_type_member_definition.append (fun);
}
+ if (requires_array_move) {
+ string_h_needed = true;
+
+ // 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 CCodeFormalParameter ("array", "gpointer"));
+ fun.add_parameter (new CCodeFormalParameter ("element_size", "gsize"));
+ fun.add_parameter (new CCodeFormalParameter ("src", "gint"));
+ fun.add_parameter (new CCodeFormalParameter ("dest", "gint"));
+ fun.add_parameter (new CCodeFormalParameter ("length", "gint"));
+ source_type_member_declaration.append (fun.copy ());
+
+ var array = new CCodeIdentifier ("array");
+ var element_size = new CCodeIdentifier ("element_size");
+ var length = new CCodeIdentifier ("length");
+ var src = new CCodeIdentifier ("src");
+ var dest = new CCodeIdentifier ("dest");
+ 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, new CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, dest, length)), element_size));
+
+ fun.block = new CCodeBlock ();
+
+ 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));
+ fun.block.add_statement (new CCodeExpressionStatement (ccall));
+
+ 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 CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, dest, src)), element_size));
+ var czeroblock1 = new CCodeBlock ();
+ czeroblock1.add_statement (new CCodeExpressionStatement (czero1));
+
+ 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 CCodeParenthesizedExpression (new CCodeBinaryExpression (CCodeBinaryOperator.MINUS, src, dest)), element_size));
+ var czeroblock2 = new CCodeBlock ();
+ czeroblock2.add_statement (new CCodeExpressionStatement (czero2));
+
+ fun.block.add_statement (new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.LESS_THAN, src, dest), czeroblock1, czeroblock2));
+
+ source_type_member_definition.append (fun);
+ }
+ if (string_h_needed) {
+ source_include_directives.append (new CCodeIncludeDirective ("string.h"));
+ }
+
CCodeComment comment = null;
if (source_file.comment != null) {
comment = new CCodeComment (source_file.comment);
valaarraylengthfield.c \
valaarraylengthfield.h \
valaarraylengthfield.vala \
+ valaarraymovemethod.c \
+ valaarraymovemethod.h \
+ valaarraymovemethod.vala \
valaarrayresizemethod.c \
valaarrayresizemethod.h \
valaarrayresizemethod.vala \
valaaddressofexpression.h \
valaarray.h \
valaarraycreationexpression.h \
+ valaarraylengthfield.h \
+ valaarraymovemethod.h \
+ valaarrayresizemethod.h \
valaassignment.h \
valaattribute.h \
valaattributeprocessor.h \
private string cname;
private ArrayLengthField length_field;
-
private ArrayResizeMethod resize_method;
+ private ArrayMoveMethod move_method;
public Array (DataType! _element_type, int _rank, SourceReference _source_reference) {
rank = _rank;
}
return resize_method;
}
+
+ public ArrayMoveMethod get_move_method () {
+ if (move_method == null) {
+ move_method = new ArrayMoveMethod (source_reference);
+
+ move_method.return_type = new TypeReference ();
+ move_method.access = MemberAccessibility.PUBLIC;
+
+ move_method.set_cname ("_vala_array_move");
+
+ var root_symbol = source_reference.file.context.root;
+ var int_type = new TypeReference ();
+ int_type.data_type = (DataType) root_symbol.scope.lookup ("int");
+
+ move_method.add_parameter (new FormalParameter ("src", int_type));
+ move_method.add_parameter (new FormalParameter ("dest", int_type));
+ move_method.add_parameter (new FormalParameter ("length", int_type));
+ }
+ return move_method;
+ }
}
--- /dev/null
+/* valaarraymovemethod.vala
+ *
+ * Copyright (C) 2007 Jürg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author:
+ * Jürg Billeter <j@bitron.ch>
+ */
+
+using GLib;
+
+/**
+ * Represents the Array.move method.
+ */
+public class Vala.ArrayMoveMethod : Method {
+ /**
+ * Creates a new array move method.
+ *
+ * @return newly created method
+ */
+ public ArrayMoveMethod (construct SourceReference source_reference) {
+ name = "move";
+ }
+}
new_array_type.scope.add (new_array_type.get_length_field ().name, new_array_type.get_length_field ());
/* add internal resize method */
new_array_type.scope.add (new_array_type.get_resize_method ().name, new_array_type.get_resize_method ());
+ /* add internal move method */
+ new_array_type.scope.add (new_array_type.get_move_method ().name, new_array_type.get_move_method ());
/* link the array type to the same source as the container type */
new_array_type.source_reference = this.source_reference;
new_array_type.scope.add (new_array_type.get_length_field ().name, new_array_type.get_length_field ());
/* add internal resize method */
new_array_type.scope.add (new_array_type.get_resize_method ().name, new_array_type.get_resize_method ());
+ /* add internal move method */
+ new_array_type.scope.add (new_array_type.get_move_method ().name, new_array_type.get_move_method ());
/* link the array type to the same source as the container type */
new_array_type.source_reference = this.source_reference;