add move method to arrays
authorJuerg Billeter <j@bitron.ch>
Fri, 27 Jul 2007 13:34:55 +0000 (13:34 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Fri, 27 Jul 2007 13:34:55 +0000 (13:34 +0000)
2007-07-27  Juerg 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

svn path=/trunk/; revision=405

ChangeLog
gobject/valacodegenerator.vala
gobject/valacodegeneratorinvocationexpression.vala
gobject/valacodegeneratorsourcefile.vala
vala/Makefile.am
vala/valaarray.vala
vala/valaarraymovemethod.vala [new file with mode: 0644]
vala/valadatatype.vala
vala/valatypeparameter.vala

index ae11f57..db74f1b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 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>
index 89c7749..f1cae2f 100644 (file)
@@ -113,6 +113,7 @@ public class Vala.CodeGenerator : CodeVisitor {
        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;
index 4c90742..104f285 100644 (file)
@@ -52,6 +52,8 @@ public class Vala.CodeGenerator {
                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
@@ -93,7 +95,14 @@ public class Vala.CodeGenerator {
                                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;
index 350b03e..cb1e984 100644 (file)
@@ -47,6 +47,7 @@ public class Vala.CodeGenerator {
                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"));
@@ -104,10 +105,6 @@ public class Vala.CodeGenerator {
 
                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)))"));
@@ -154,7 +151,60 @@ public class Vala.CodeGenerator {
 
                        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);
index fe04e51..922b70a 100644 (file)
@@ -28,6 +28,9 @@ libvalacore_la_SOURCES = \
        valaarraylengthfield.c \
        valaarraylengthfield.h \
        valaarraylengthfield.vala \
+       valaarraymovemethod.c \
+       valaarraymovemethod.h \
+       valaarraymovemethod.vala \
        valaarrayresizemethod.c \
        valaarrayresizemethod.h \
        valaarrayresizemethod.vala \
@@ -322,6 +325,9 @@ valainclude_HEADERS = \
        valaaddressofexpression.h \
        valaarray.h \
        valaarraycreationexpression.h \
+       valaarraylengthfield.h \
+       valaarraymovemethod.h \
+       valaarrayresizemethod.h \
        valaassignment.h \
        valaattribute.h \
        valaattributeprocessor.h \
index 116074a..e545ec3 100644 (file)
@@ -46,8 +46,8 @@ public class Vala.Array : DataType {
        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;
@@ -175,4 +175,24 @@ public class Vala.Array : DataType {
                }
                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;
+       }
 }
diff --git a/vala/valaarraymovemethod.vala b/vala/valaarraymovemethod.vala
new file mode 100644 (file)
index 0000000..36ae9e7
--- /dev/null
@@ -0,0 +1,37 @@
+/* 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";
+       }
+}
index cbb7f3b..ac2eecd 100644 (file)
@@ -246,6 +246,8 @@ public abstract class Vala.DataType : Symbol {
                        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;
index bf73bb4..5867d25 100644 (file)
@@ -68,6 +68,8 @@ public class Vala.TypeParameter : Symbol {
                        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;