From: Vladyslav Stovmanenko Date: Wed, 11 May 2022 10:02:27 +0000 (+0000) Subject: Add support for freeing non-pointer elements in the arrays. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5e53939eee0885cb24a76ea636390af6ca72562b;p=thirdparty%2Fvala.git Add support for freeing non-pointer elements in the arrays. --- 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)); + } } } }