[vala/wip/682_array_methods_refactor: 12/18] Add support for freeing non-pointer elements in the arrays.




commit 5e53939eee0885cb24a76ea636390af6ca72562b
Author: Vladyslav Stovmanenko <flaviusglamfenix gmail com>
Date:   Wed May 11 10:02:27 2022 +0000

    Add support for freeing non-pointer elements in the arrays.

 codegen/valaccodearraymodule.vala      | 56 +++++++++++++++++++++++++++++-----
 codegen/valaccodemethodcallmodule.vala |  8 +++--
 tests/basic-types/arrays.c-expected    | 36 +++++++++++++++++-----
 tests/posix/arrays.c-expected          | 36 +++++++++++++++++-----
 4 files changed, 110 insertions(+), 26 deletions(-)
---
diff --git a/codegen/valaccodearraymodule.vala b/codegen/valaccodearraymodule.vala
index 0b8c6d662..9f6590c3c 100644
--- a/codegen/valaccodearraymodule.vala
+++ b/codegen/valaccodearraymodule.vala
@@ -391,12 +391,14 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                var null_id = new CCodeIdentifier("NULL");
                var free_func = new CCodeIdentifier("free_func");
                var array_id = new CCodeIdentifier ("array");
+               var is_pointer_id = new CCodeIdentifier ("is_pointer");
 
                var fun = new CCodeFunction ("_vala_array_move", "void");
                fun.modifiers = CCodeModifiers.STATIC;
                fun.add_parameter (new CCodeParameter (array_id.name, get_ccode_name (pointer_type)));
                fun.add_parameter (new CCodeParameter ("element_size", get_ccode_name (size_t_type)));
                fun.add_parameter (new CCodeParameter (free_func.name, get_ccode_name 
(delegate_target_destroy_type)));
+               fun.add_parameter (new CCodeParameter (is_pointer_id.name, get_ccode_name (bool_type)));
                fun.add_parameter (new CCodeParameter ("src", get_ccode_name (ssize_t_type)));
                fun.add_parameter (new CCodeParameter ("dest", get_ccode_name (ssize_t_type)));
                fun.add_parameter (new CCodeParameter ("length", get_ccode_name (ssize_t_type)));
@@ -419,7 +421,7 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                var moving_back_overlapping = new CCodeBinaryExpression (CCodeBinaryOperator.AND, new 
CCodeBinaryExpression (CCodeBinaryOperator.GREATER_THAN, src, dest), new CCodeBinaryExpression 
(CCodeBinaryOperator.LESS_THAN, src, dest_end));
                var move_without_overlapping = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, 
src, dest);
 
-               var free_func_not_null_check = new CCodeBinaryExpression(CCodeBinaryOperator.INEQUALITY, 
free_func, null_id);
+               var free_func_not_null_check = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, 
free_func, null_id);
                ccode.open_if (free_func_not_null_check);
 
                ccode.open_if (moving_forward_overlapping);
@@ -433,12 +435,26 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                var cond_expr = new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, iterator_var, 
src_end);
                var iter_expr = new CCodeUnaryExpression(CCodeUnaryOperator.POSTFIX_INCREMENT, iterator_var);
 
+               ccode.open_if (is_pointer_id);
+
                ccode.open_for(init_expr, cond_expr, iter_expr);
-               var accessed_element = new CCodeElementAccess(void_array, iterator_var);
+               var accessed_element = new CCodeElementAccess (void_array, iterator_var);
                var free_call = new CCodeFunctionCall(free_func);
-               free_call.add_argument(accessed_element);
-               ccode.add_expression(free_call);
+               free_call.add_argument (accessed_element);
+               ccode.add_expression (free_call);
 
+               ccode.close ();
+
+               ccode.add_else ();
+
+               ccode.open_for(init_expr, cond_expr, iter_expr);
+               var offset = new CCodeBinaryExpression(CCodeBinaryOperator.MUL, iterator_var, element_size);
+               var address_to_clean = new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, array, offset);
+               free_call = new CCodeFunctionCall(free_func);
+               free_call.add_argument (address_to_clean);
+               ccode.add_expression (free_call);
+
+               ccode.close();
                ccode.close();
 
                ccode.else_if(moving_back_overlapping);
@@ -449,14 +465,25 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                cond_expr = new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, iterator_var, src);
                iter_expr = new CCodeUnaryExpression(CCodeUnaryOperator.POSTFIX_INCREMENT, iterator_var);
 
+               ccode.open_if (is_pointer_id);
+
                ccode.open_for(init_expr, cond_expr, iter_expr);
-               accessed_element = new CCodeElementAccess(void_array, iterator_var);
                free_call = new CCodeFunctionCall(free_func);
                free_call.add_argument(accessed_element);
                ccode.add_expression(free_call);
 
                ccode.close();
 
+               ccode.add_else ();
+
+               ccode.open_for(init_expr, cond_expr, iter_expr);
+               free_call = new CCodeFunctionCall(free_func);
+               free_call.add_argument (address_to_clean);
+               ccode.add_expression (free_call);
+
+               ccode.close();
+               ccode.close();
+
                ccode.else_if(move_without_overlapping);
 
                ccode.add_declaration (get_ccode_name (ssize_t_type), iterator_declarator);
@@ -465,15 +492,28 @@ public class Vala.CCodeArrayModule : CCodeMethodCallModule {
                cond_expr = new CCodeBinaryExpression(CCodeBinaryOperator.LESS_THAN, iterator_var, dest_end);
                iter_expr = new CCodeUnaryExpression(CCodeUnaryOperator.POSTFIX_INCREMENT, iterator_var);
 
+               ccode.open_if (is_pointer_id);
+
                ccode.open_for(init_expr, cond_expr, iter_expr);
                accessed_element = new CCodeElementAccess(void_array, iterator_var);
                free_call = new CCodeFunctionCall(free_func);
                free_call.add_argument(accessed_element);
                ccode.add_expression(free_call);
 
-               ccode.close(); //close cycle
-               ccode.close(); //close endif
-               ccode.close(); //close if for free_func_not_null_check
+               ccode.close(); /*close cycle*/
+
+               ccode.add_else ();
+
+               ccode.open_for(init_expr, cond_expr, iter_expr);
+               free_call = new CCodeFunctionCall(free_func);
+               free_call.add_argument (address_to_clean);
+               ccode.add_expression (free_call);
+
+               ccode.close(); /*close cycle*/
+               ccode.close(); /*close is_pointer_check*/
+
+               ccode.close(); /*close endif*/
+               ccode.close(); /*close if for free_func_not_null_check*/
 
                var ccall = new CCodeFunctionCall (new CCodeIdentifier ("memmove"));
                ccall.add_argument (dest_address);
diff --git a/codegen/valaccodemethodcallmodule.vala b/codegen/valaccodemethodcallmodule.vala
index 825b9c7c6..2f1f62568 100644
--- a/codegen/valaccodemethodcallmodule.vala
+++ b/codegen/valaccodemethodcallmodule.vala
@@ -338,12 +338,16 @@ public class Vala.CCodeMethodCallModule : CCodeAssignmentModule {
                        csizeof.add_argument (new CCodeIdentifier (get_ccode_name (array_type.element_type)));
                        in_arg_map.set (get_param_pos (0.1), csizeof);
 
-                       CCodeExpression free_func_expr = new CCodeIdentifier("NULL");
+                       CCodeExpression free_func_expr = new CCodeIdentifier ("NULL");
                        if (array_type.element_type.value_owned) {
-                               free_func_expr = get_destroy_func_expression(array_type.element_type);
+                               free_func_expr = get_destroy_func_expression (array_type.element_type);
                        }
 
                        in_arg_map.set (get_param_pos (0.2), free_func_expr);
+
+                       CCodeExpression is_pointer = get_boolean_cconstant (array_type.element_type.nullable 
|| array_type.element_type.is_reference_type_or_type_parameter ());
+
+                       in_arg_map.set (get_param_pos (0.3), is_pointer);
                } else if (m is DynamicMethod) {
                        emit_context.push_symbol (m);
                        m.clear_parameters ();
diff --git a/tests/basic-types/arrays.c-expected b/tests/basic-types/arrays.c-expected
index 6ffe7bb00..e3bf50eef 100644
--- a/tests/basic-types/arrays.c-expected
+++ b/tests/basic-types/arrays.c-expected
@@ -183,6 +183,7 @@ static void _vala_array_free (gpointer array,
 static void _vala_array_move (gpointer array,
                        gsize element_size,
                        GDestroyNotify free_func,
+                       gboolean is_pointer,
                        gssize src,
                        gssize dest,
                        gssize length);
@@ -1341,7 +1342,7 @@ test_array_with_primitives_move (void)
        _a_size_ = a_length1;
        _tmp1_ = a[4];
        _vala_assert (_tmp1_ == 5, "a[4] == 5");
-       _vala_array_move (a, sizeof (gint), NULL, 4, 0, 5);
+       _vala_array_move (a, sizeof (gint), NULL, FALSE, 4, 0, 5);
        _tmp2_ = a[4];
        _vala_assert (_tmp2_ == 9, "a[4] == 9");
        _tmp3_ = a[8];
@@ -1445,7 +1446,7 @@ test_array_with_struct_move (gint src,
        _tmp5__length1 = arr_length1;
        _tmp6_ = _tmp5_[src];
        testObj = _tmp6_;
-       _vala_array_move (arr, sizeof (TestMoveCall), NULL, src, dest, count);
+       _vala_array_move (arr, sizeof (TestMoveCall), NULL, FALSE, src, dest, count);
        _tmp7_ = arr;
        _tmp7__length1 = arr_length1;
        _tmp8_ = _tmp7_[dest];
@@ -1807,6 +1808,7 @@ static void
 _vala_array_move (gpointer array,
                   gsize element_size,
                   GDestroyNotify free_func,
+                  gboolean is_pointer,
                   gssize src,
                   gssize dest,
                   gssize length)
@@ -1814,18 +1816,36 @@ _vala_array_move (gpointer array,
        if (free_func != NULL) {
                if ((src < dest) && ((src + length) > dest)) {
                        gssize i;
-                       for (i = dest; i < (src + length); i++) {
-                               free_func (((void**) array)[i]);
+                       if (is_pointer) {
+                               for (i = dest; i < (src + length); i++) {
+                                       free_func (((void**) array)[i]);
+                               }
+                       } else {
+                               for (i = dest; i < (src + length); i++) {
+                                       free_func (((char*) array) + (i * element_size));
+                               }
                        }
                } else if ((src > dest) && (src < (dest + length))) {
                        gssize i;
-                       for (i = dest; i < src; i++) {
-                               free_func (((void**) array)[i]);
+                       if (is_pointer) {
+                               for (i = dest; i < src; i++) {
+                                       free_func (((void**) array)[i]);
+                               }
+                       } else {
+                               for (i = dest; i < src; i++) {
+                                       free_func (((char*) array) + (i * element_size));
+                               }
                        }
                } else if (src != dest) {
                        gssize i;
-                       for (i = dest; i < (dest + length); i++) {
-                               free_func (((void**) array)[i]);
+                       if (is_pointer) {
+                               for (i = dest; i < (dest + length); i++) {
+                                       free_func (((void**) array)[i]);
+                               }
+                       } else {
+                               for (i = dest; i < (dest + length); i++) {
+                                       free_func (((char*) array) + (i * element_size));
+                               }
                        }
                }
        }
diff --git a/tests/posix/arrays.c-expected b/tests/posix/arrays.c-expected
index 6f3b664f3..17012c236 100644
--- a/tests/posix/arrays.c-expected
+++ b/tests/posix/arrays.c-expected
@@ -171,6 +171,7 @@ static void _vala_array_free (void* array,
 static void _vala_array_move (void* array,
                        size_t element_size,
                        ValaDestroyNotify free_func,
+                       bool is_pointer,
                        ssize_t src,
                        ssize_t dest,
                        ssize_t length);
@@ -1376,7 +1377,7 @@ test_array_with_primitives_move (void)
        _a_size_ = a_length1;
        _tmp1_ = a[4];
        assert (_tmp1_ == 5);
-       _vala_array_move (a, sizeof (int), NULL, 4, 0, 5);
+       _vala_array_move (a, sizeof (int), NULL, false, 4, 0, 5);
        _tmp2_ = a[4];
        assert (_tmp2_ == 9);
        _tmp3_ = a[8];
@@ -1460,7 +1461,7 @@ test_array_with_struct_move (int src,
        _tmp5__length1 = arr_length1;
        _tmp6_ = _tmp5_[src];
        testObj = _tmp6_;
-       _vala_array_move (arr, sizeof (TestMoveCall), NULL, src, dest, count);
+       _vala_array_move (arr, sizeof (TestMoveCall), NULL, false, src, dest, count);
        _tmp7_ = arr;
        _tmp7__length1 = arr_length1;
        _tmp8_ = _tmp7_[dest];
@@ -1762,6 +1763,7 @@ static void
 _vala_array_move (void* array,
                   size_t element_size,
                   ValaDestroyNotify free_func,
+                  bool is_pointer,
                   ssize_t src,
                   ssize_t dest,
                   ssize_t length)
@@ -1769,18 +1771,36 @@ _vala_array_move (void* array,
        if (free_func != NULL) {
                if ((src < dest) && ((src + length) > dest)) {
                        ssize_t i;
-                       for (i = dest; i < (src + length); i++) {
-                               free_func (((void**) array)[i]);
+                       if (is_pointer) {
+                               for (i = dest; i < (src + length); i++) {
+                                       free_func (((void**) array)[i]);
+                               }
+                       } else {
+                               for (i = dest; i < (src + length); i++) {
+                                       free_func (((char*) array) + (i * element_size));
+                               }
                        }
                } else if ((src > dest) && (src < (dest + length))) {
                        ssize_t i;
-                       for (i = dest; i < src; i++) {
-                               free_func (((void**) array)[i]);
+                       if (is_pointer) {
+                               for (i = dest; i < src; i++) {
+                                       free_func (((void**) array)[i]);
+                               }
+                       } else {
+                               for (i = dest; i < src; i++) {
+                                       free_func (((char*) array) + (i * element_size));
+                               }
                        }
                } else if (src != dest) {
                        ssize_t i;
-                       for (i = dest; i < (dest + length); i++) {
-                               free_func (((void**) array)[i]);
+                       if (is_pointer) {
+                               for (i = dest; i < (dest + length); i++) {
+                                       free_func (((void**) array)[i]);
+                               }
+                       } else {
+                               for (i = dest; i < (dest + length); i++) {
+                                       free_func (((char*) array) + (i * element_size));
+                               }
                        }
                }
        }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]