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};