all repos — hex @ d848fa18e3e594b9e960c3af374c2101de7a211e

A tiny, minimalist, slightly-esoteric, concatenative programming lannguage.

Added missing free actions in some cases; other fixes.
h3rald h3rald@h3rald.com
Thu, 25 Jun 2026 11:02:14 +0200
commit

d848fa18e3e594b9e960c3af374c2101de7a211e

parent

9574974de9d7a89bde0c98e48e6c9af4e84e0296

4 files changed, 20 insertions(+), 18 deletions(-)

jump to
M src/hex.csrc/hex.c

@@ -1158,9 +1158,8 @@ /*

* hex_set_symbol * Ownership contract: * - Caller passes a heap-allocated hex_item_t* (value). - * - This function ALWAYS consumes (frees) the passed pointer, whether it succeeds or fails. - * - The registry stores its own deep copy (value_copy) and becomes sole owner. - * - Callers MUST NOT use or free the original pointer after calling. + * - The registry stores its own deep copy and becomes sole owner. + * - Callers must not use or free the original pointer after calling. * - Rationale: prevents aliasing between caller's pointer and registry entry, eliminating * double free / accidental mutation risks. */

@@ -3122,7 +3121,7 @@ (*size)--;

hex_debug(ctx, ">> PUSHQT[03]: <start> (items: %zu)", n_items); - hex_item_t **items = (hex_item_t **)malloc(n_items * sizeof(hex_item_t)); + hex_item_t **items = (hex_item_t **)malloc(n_items * sizeof(hex_item_t *)); if (!items) { hex_error(ctx, "[interpret bytecode quotation] Memory allocation failed");

@@ -5473,10 +5472,7 @@ {

hex_error(ctx, "[symbol len] Quotation or string required"); result = 1; } - if (result != 0) - { - HEX_FREE(ctx, item); - } + HEX_FREE(ctx, item); return result; }

@@ -5589,6 +5585,8 @@ HEX_FREE(ctx, list);

HEX_FREE(ctx, item); return 1; } + HEX_FREE(ctx, list); + HEX_FREE(ctx, item); return hex_push_integer(ctx, result); }

@@ -6503,8 +6501,10 @@ HEX_POP(ctx, evalResult);

if (evalResult->type == HEX_TYPE_INTEGER && evalResult->data.int_value == 0) { // Don't free evalResult here as it might be shared - let normal cleanup handle it + HEX_FREE(ctx, evalResult); break; } + HEX_FREE(ctx, evalResult); hex_item_t *act = hex_copy_item(ctx, action); for (size_t i = 0; i < act->quotation_size; i++)

@@ -6513,8 +6513,9 @@ // Create a copy to avoid ownership issues

hex_item_t *copy = hex_copy_item(ctx, act->data.quotation_value[i]); if (!copy || hex_push(ctx, copy) != 0) { - if (copy) + if (copy) { hex_free_item(ctx, copy); + } HEX_FREE(ctx, act); HEX_FREE(ctx, action); HEX_FREE(ctx, condition);
M src/registry.csrc/registry.c

@@ -158,9 +158,8 @@ /*

* hex_set_symbol * Ownership contract: * - Caller passes a heap-allocated hex_item_t* (value). - * - This function ALWAYS consumes (frees) the passed pointer, whether it succeeds or fails. - * - The registry stores its own deep copy (value_copy) and becomes sole owner. - * - Callers MUST NOT use or free the original pointer after calling. + * - The registry stores its own deep copy and becomes sole owner. + * - Callers must not use or free the original pointer after calling. * - Rationale: prevents aliasing between caller's pointer and registry entry, eliminating * double free / accidental mutation risks. */
M src/symbols.csrc/symbols.c

@@ -1443,10 +1443,7 @@ {

hex_error(ctx, "[symbol len] Quotation or string required"); result = 1; } - if (result != 0) - { - HEX_FREE(ctx, item); - } + HEX_FREE(ctx, item); return result; }

@@ -1559,6 +1556,8 @@ HEX_FREE(ctx, list);

HEX_FREE(ctx, item); return 1; } + HEX_FREE(ctx, list); + HEX_FREE(ctx, item); return hex_push_integer(ctx, result); }

@@ -2473,8 +2472,10 @@ HEX_POP(ctx, evalResult);

if (evalResult->type == HEX_TYPE_INTEGER && evalResult->data.int_value == 0) { // Don't free evalResult here as it might be shared - let normal cleanup handle it + HEX_FREE(ctx, evalResult); break; } + HEX_FREE(ctx, evalResult); hex_item_t *act = hex_copy_item(ctx, action); for (size_t i = 0; i < act->quotation_size; i++)

@@ -2483,8 +2484,9 @@ // Create a copy to avoid ownership issues

hex_item_t *copy = hex_copy_item(ctx, act->data.quotation_value[i]); if (!copy || hex_push(ctx, copy) != 0) { - if (copy) + if (copy) { hex_free_item(ctx, copy); + } HEX_FREE(ctx, act); HEX_FREE(ctx, action); HEX_FREE(ctx, condition);
M src/vm.csrc/vm.c

@@ -545,7 +545,7 @@ (*size)--;

hex_debug(ctx, ">> PUSHQT[03]: <start> (items: %zu)", n_items); - hex_item_t **items = (hex_item_t **)malloc(n_items * sizeof(hex_item_t)); + hex_item_t **items = (hex_item_t **)malloc(n_items * sizeof(hex_item_t *)); if (!items) { hex_error(ctx, "[interpret bytecode quotation] Memory allocation failed");