1#include "src/pw_alloc.h"
  2#include "src/types/struct_internal.h"
  3
  4[[nodiscard]] uint8_t* _pw_struct_alloc(uint16_t type_id)
  5{
  6    PwType* type = _pw_types[type_id];
  7
  8    // allocate memory
  9
 10    _PwStructData* struct_data = _pw_alloc(type_id, type->total_struct_size, true);
 11    if (!struct_data) {
 12        return nullptr;
 13    }
 14
 15    _pw_atomic_store(&struct_data->refcount, 1);
 16    _pw_atomic_store(&struct_data->itercount, 0);
 17    return (uint8_t*) struct_data;
 18}
 19
 20static bool struct_create(PwMethod_Basic_create* mthis, PwValuePtr result, PwCtorArgs* ctor_args)
 21{
 22    result->struct_data = _pw_struct_alloc(result->type_id);
 23    result->struct_offset = _pw_types[result->type_id]->struct_offsets[0];
 24    return (bool) result->struct_data;
 25}
 26
 27static bool struct_destroy(PwMethod_Basic_destroy* mthis, PwValuePtr self, _PwCompoundChain* tail)
 28{
 29    PwValuePtr value_seen = _pw_on_chain(self, tail);
 30    if (value_seen) {
 31        return true;
 32    }
 33    _pw_free(self->type_id, (void**) &self->struct_data, pw_typeof(self)->total_struct_size);
 34    return true;
 35}
 36
 37static bool struct_clone(PwMethod_Basic_clone* mthis, PwValuePtr self)
 38{
 39    _PwStructData* struct_data = (_PwStructData*) self->struct_data;
 40    _pw_atomic_add(&struct_data->refcount, 1);
 41    return true;
 42}
 43
 44static bool struct_decref(PwMethod_Basic_decref* mthis, PwValuePtr self)
 45{
 46    _PwStructData* struct_data = (_PwStructData*) self->struct_data;
 47    return _pw_atomic_sub(&struct_data->refcount, 1) != 1;
 48}
 49
 50static bool struct_hash(PwMethod_Basic_hash* mthis, PwValuePtr self, PwHashContext* ctx, _PwCompoundChain* tail)
 51{
 52    _pw_hash_uint64(ctx, self->type_id);
 53    _pw_hash_uint64(ctx, (uint64_t) self->struct_data);
 54    return true;
 55}
 56
 57static bool struct_deepcopy(PwMethod_Basic_deepcopy* mthis, PwValuePtr self, PwValuePtr result, _PwCompoundChain* tail)
 58{
 59    pw_set_status(PwStatus(PW_ERROR_NOT_IMPLEMENTED));
 60    return false;
 61}
 62
 63static bool struct_dump(PwMethod_Basic_dump* mthis, PwValuePtr self, FILE* fp, int indent, _PwCompoundChain* tail)
 64{
 65    _pw_print_indent(fp, indent);
 66    _pw_print_type(fp, self);
 67
 68    _PwStructData* struct_data = (_PwStructData*) self->struct_data;
 69
 70    if (struct_data) {
 71        fprintf(fp, "; data=%p refcount=%u itercount=%u\n",
 72                (void*) struct_data, _pw_atomic_load(&struct_data->refcount), _pw_atomic_load(&struct_data->itercount));
 73    } else {
 74        fputs("; data=NULL\n", fp);
 75    }
 76    return true;
 77}
 78
 79static bool struct_to_string(PwMethod_Basic_to_string* mthis, PwValuePtr self, PwValuePtr result, _PwCompoundChain* tail)
 80{
 81    pw_set_status(PwStatus(PW_ERROR_NOT_IMPLEMENTED));
 82    return false;
 83}
 84
 85static bool struct_is_true(PwMethod_Basic_is_true* mthis, PwValuePtr self, _PwCompoundChain* tail)
 86{
 87    return false;
 88}
 89
 90[[nodiscard]] static bool struct_eq(PwValuePtr self, PwValuePtr other)
 91{
 92    // basic Structs are empty and empty always equals empty
 93    return true;
 94}
 95
 96static bool struct_equal(PwMethod_Basic_equal* mthis, PwValuePtr self, PwValuePtr other, _PwCompoundChain* tail)
 97{
 98    PW_EQUAL_METHOD_IMPL(PwTypeId_Struct, struct_eq, self, other);
 99    return false;
100}
101
102#define struct_iter_children nullptr
103
104PwInterface_Basic _pw_struct_basic_interface = {
105#define X(name, ...) .name = { .func = struct_##name } __VA_OPT__(,)
106    PW_BASIC_INTERFACE_METHODS
107#undef X
108};