From b49e7bae77c537a08cf5c5cb1850fc34d859252a Mon Sep 17 00:00:00 2001 From: Juerg Billeter Date: Fri, 27 Jul 2007 13:34:55 +0000 Subject: [PATCH] add move method to arrays 2007-07-27 Juerg Billeter * 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 | 8 +++ gobject/valacodegenerator.vala | 1 + gobject/valacodegeneratorinvocationexpression.vala | 11 +++- gobject/valacodegeneratorsourcefile.vala | 58 ++++++++++++++++++++-- vala/Makefile.am | 6 +++ vala/valaarray.vala | 22 +++++++- vala/valaarraymovemethod.vala | 37 ++++++++++++++ vala/valadatatype.vala | 2 + vala/valatypeparameter.vala | 2 + 9 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 vala/valaarraymovemethod.vala diff --git a/ChangeLog b/ChangeLog index ae11f57..db74f1b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ 2007-07-27 Jürg Billeter + * 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 + * vala/valasemanticanalyzer.vala: fix warning when connecting signals 2007-07-27 Jürg Billeter diff --git a/gobject/valacodegenerator.vala b/gobject/valacodegenerator.vala index 89c7749..f1cae2f 100644 --- a/gobject/valacodegenerator.vala +++ b/gobject/valacodegenerator.vala @@ -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; diff --git a/gobject/valacodegeneratorinvocationexpression.vala b/gobject/valacodegeneratorinvocationexpression.vala index 4c90742..104f285 100644 --- a/gobject/valacodegeneratorinvocationexpression.vala +++ b/gobject/valacodegeneratorinvocationexpression.vala @@ -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; diff --git a/gobject/valacodegeneratorsourcefile.vala b/gobject/valacodegeneratorsourcefile.vala index 350b03e..cb1e984 100644 --- a/gobject/valacodegeneratorsourcefile.vala +++ b/gobject/valacodegeneratorsourcefile.vala @@ -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); diff --git a/vala/Makefile.am b/vala/Makefile.am index fe04e51..922b70a 100644 --- a/vala/Makefile.am +++ b/vala/Makefile.am @@ -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 \ diff --git a/vala/valaarray.vala b/vala/valaarray.vala index 116074a..e545ec3 100644 --- a/vala/valaarray.vala +++ b/vala/valaarray.vala @@ -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 index 0000000..36ae9e7 --- /dev/null +++ b/vala/valaarraymovemethod.vala @@ -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 + */ + +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"; + } +} diff --git a/vala/valadatatype.vala b/vala/valadatatype.vala index cbb7f3b..ac2eecd 100644 --- a/vala/valadatatype.vala +++ b/vala/valadatatype.vala @@ -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; diff --git a/vala/valatypeparameter.vala b/vala/valatypeparameter.vala index bf73bb4..5867d25 100644 --- a/vala/valatypeparameter.vala +++ b/vala/valatypeparameter.vala @@ -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; -- 2.7.4