array: fix a crash in array_create if memory allocation failed and had to
[ajla.git] / cg-flcch.inc
blobe2ed9c16502faee9fe1035f5939982a6acf68cae
1 /*
2  * Copyright (C) 2024 Mikulas Patocka
3  *
4  * This file is part of Ajla.
5  *
6  * Ajla is free software: you can redistribute it and/or modify it under the
7  * terms of the GNU General Public License as published by the Free Software
8  * Foundation, either version 3 of the License, or (at your option) any later
9  * version.
10  *
11  * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13  * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * Ajla. If not, see <https://www.gnu.org/licenses/>.
17  */
19 static bool attr_w clear_flag_cache(struct codegen_context *ctx)
21         memset(ctx->flag_cache, 0, function_n_variables(ctx->fn) * sizeof(int8_t));
22         return true;
25 /*#define clear_flag_cache(ctx) \
26         (debug("clearing flag cache @ %d", __LINE__), memset((ctx)->flag_cache, 0, function_n_variables(ctx->fn) * sizeof(int8_t)), true)*/
28 static inline void flag_set(struct codegen_context *ctx, frame_t slot, bool val)
30         unsigned c;
31         if (val && !must_be_flat_chicken && da(ctx->fn,function)->local_variables_flags[slot].must_be_flat) {
32                 internal(file_line, "flag_set: %s: setting slot %lu as not flat", da(ctx->fn,function)->function_name, (unsigned long)slot);
33         }
34         c = ctx->flag_cache[slot] & ~(FLAG_CACHE_IS_FLAT | FLAG_CACHE_IS_NOT_FLAT);
35         ctx->flag_cache[slot] = c | (!val ? FLAG_CACHE_IS_FLAT : FLAG_CACHE_IS_NOT_FLAT);
38 static inline void flag_set_unknown(struct codegen_context *ctx, frame_t slot)
40         ctx->flag_cache[slot] = 0;
43 static inline bool flag_must_be_flat(struct codegen_context *ctx, frame_t slot)
45         if (!must_be_flat_chicken && da(ctx->fn,function)->local_variables_flags[slot].must_be_flat) {
46                 if (unlikely((ctx->flag_cache[slot] & FLAG_CACHE_IS_NOT_FLAT) != 0))
47                         internal(file_line, "flag_must_be_flat: %s: must_be_flat slot %lu is not flat", da(ctx->fn,function)->function_name, (unsigned long)slot);
48                 return true;
49         }
50         return false;
53 static inline bool flag_is_clear(struct codegen_context *ctx, frame_t slot)
55         if (!flag_cache_chicken && ctx->flag_cache[slot] & FLAG_CACHE_IS_FLAT)
56                 return true;
57         if (flag_must_be_flat(ctx, slot))
58                 return true;
59         return false;
62 static inline bool flag_is_set(struct codegen_context *ctx, frame_t slot)
64         if (!flag_cache_chicken && ctx->flag_cache[slot] & FLAG_CACHE_IS_NOT_FLAT)
65                 return true;
66         return false;
69 static bool attr_w gen_test_1_cached(struct codegen_context *ctx, frame_t slot_1, uint32_t label)
71         if (flag_is_clear(ctx, slot_1))
72                 return true;
73         return gen_test_1(ctx, R_FRAME, slot_1, 0, label, false, TEST);
76 static bool attr_w gen_test_2_cached(struct codegen_context *ctx, frame_t slot_1, frame_t slot_2, uint32_t label)
78         if (flag_is_clear(ctx, slot_1))
79                 return gen_test_1_cached(ctx, slot_2, label);
80         if (flag_is_clear(ctx, slot_2))
81                 return gen_test_1_cached(ctx, slot_1, label);
82         return gen_test_2(ctx, slot_1, slot_2, label);
85 static bool attr_w gen_test_1_jz_cached(struct codegen_context *ctx, frame_t slot_1, uint32_t label)
87         const struct type *type = get_type_of_local(ctx, slot_1);
88         if (!TYPE_IS_FLAT(type) && !da(ctx->fn,function)->local_variables_flags[slot_1].may_be_borrowed)
89                 return true;
90         if (flag_is_set(ctx, slot_1))
91                 return true;
92         return gen_test_1(ctx, R_FRAME, slot_1, 0, label, true, TEST);