1#include "src/pw_alloc.h"
2#include "src/types/struct_internal.h"
3
4[[nodiscard]] bool _pw_struct_alloc(PwValuePtr value)
5{
6 PwType* type = _pw_types[value->type_id];
7
8 // allocate memory
9
10 _PwStructData* struct_data = _pw_alloc(value->type_id, type->total_struct_size, true);
11 if (!struct_data) {
12 return false;
13 }
14 value->struct_data = (uint8_t*) struct_data;
15 value->struct_offset = type->struct_offsets[0];
16
17 _pw_atomic_store(&struct_data->refcount, 1);
18 _pw_atomic_store(&struct_data->itercount, 0);
19 return true;
20}
21
22static bool struct_create(PwMethod_Basic_create* mthis, PwValuePtr result, PwCtorArgs* ctor_args)
23{
24 return _pw_struct_alloc(result);
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(PweNotImplemented));
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(PweNotImplemented));
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
90static bool struct_equal(PwMethod_Basic_equal* mthis, PwValuePtr self, PwValuePtr other, _PwCompoundChain* tail)
91{
92 if (other->type_id != PwTypeId_Struct) {
93 // there's no point to compare with base types; types must match exactly
94 return false;
95 }
96 // basic Structs are empty and empty always equals empty
97 return true;
98}
99
100#define struct_is_immutable nullptr
101#define struct_iter_children nullptr
102
103PwInterface_Basic _pw_struct_basic_interface = {
104#define X(name, ...) .name = { .func = struct_##name } __VA_OPT__(,)
105 PW_BASIC_INTERFACE_METHODS
106#undef X
107};