mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-06-13 07:32:23 -07:00
finish first pass sketching out basic base-layer-defined codebase type info & serialization/deserialization path with basic pointer cases
This commit is contained in:
+1
-1
@@ -46,7 +46,7 @@ load_paths =
|
||||
commands =
|
||||
{
|
||||
//- rjf: fkey command slots (change locally but do not commit)
|
||||
.f1 = { .win = "build raddbg telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
.f1 = { .win = "build ryan_scratch", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
.f2 = { .win = "build rdi_from_pdb", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
.f3 = { .win = "pushd build && raddbg.exe --user:local_dev.raddbg_user --project:local_dev.raddbg_project --auto_step && popd",.linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, },
|
||||
|
||||
|
||||
+226
-69
@@ -8,7 +8,7 @@ internal Member *
|
||||
member_from_name(Type *type, String8 name)
|
||||
{
|
||||
Member *member = &member_nil;
|
||||
if(type->members != 0)
|
||||
if(type->members != 0 && name.size != 0)
|
||||
{
|
||||
for(U64 idx = 0; idx < type->count; idx += 1)
|
||||
{
|
||||
@@ -26,7 +26,7 @@ member_from_name(Type *type, String8 name)
|
||||
//~ rjf: Type Info * Instance Operations
|
||||
|
||||
internal String8
|
||||
serialized_from_typed_data(Arena *arena, Type *type, void *ptr, TypeSerializeParams *params)
|
||||
serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
String8List strings = {0};
|
||||
@@ -37,29 +37,30 @@ serialized_from_typed_data(Arena *arena, Type *type, void *ptr, TypeSerializePar
|
||||
{
|
||||
Task *next;
|
||||
Type *type;
|
||||
void *ptr;
|
||||
U64 count;
|
||||
U8 *src;
|
||||
Type *containing_type;
|
||||
void *containing_ptr;
|
||||
U8 *containing_ptr;
|
||||
B32 is_post_header;
|
||||
};
|
||||
Task start_task = {0, type, ptr, 1};
|
||||
Task start_task = {0, type, 1, data.str};
|
||||
Task *first_task = &start_task;
|
||||
Task *last_task = first_task;
|
||||
for(Task *t = first_task; t != 0; t = t->next)
|
||||
{
|
||||
switch(t->type->kind)
|
||||
{
|
||||
//- rjf: leaf serialiation -> just write the data directly
|
||||
//- rjf: leaf -> just copy the data directly
|
||||
default:
|
||||
if(TypeKind_FirstLeaf <= t->type->kind && t->type->kind <= TypeKind_LastLeaf)
|
||||
{
|
||||
str8_serial_push_string(scratch.arena, &strings, str8((U8 *)t->ptr, type_leaves[t->type->kind].size*t->count));
|
||||
str8_serial_push_string(scratch.arena, &strings, str8(t->src, t->type->size*t->count));
|
||||
}break;
|
||||
|
||||
//- rjf: pointers -> try to interpret/understand pointer & write, otherwise skip
|
||||
//- rjf: pointers -> try to interpret/understand pointer & read/write, otherwise skip
|
||||
case TypeKind_Ptr:
|
||||
{
|
||||
// rjf: gather info about pointer references of this type
|
||||
// rjf: unpack info about this pointer
|
||||
TypeSerializePtrRefInfo *ptr_ref_info = 0;
|
||||
for(U64 idx = 0; idx < params->ptr_ref_infos_count; idx += 1)
|
||||
{
|
||||
@@ -70,60 +71,57 @@ serialized_from_typed_data(Arena *arena, Type *type, void *ptr, TypeSerializePar
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: read ptr value
|
||||
void *ptr_value = 0;
|
||||
MemoryCopy(&ptr_value, t->ptr, sizeof(ptr_value));
|
||||
|
||||
// rjf: indexification -> subtract base, divide direct size, write index
|
||||
if(ptr_ref_info != 0 && ptr_ref_info->indexify_base != 0)
|
||||
{
|
||||
U64 ptr_offsetified = (U8 *)ptr_value - (U8 *)ptr_ref_info->indexify_base;
|
||||
U64 ptr_indexified = ptr_offsetified / t->type->direct->size;
|
||||
str8_serial_push_struct(scratch.arena, &strings, &ptr_indexified);
|
||||
U64 ptr_value = 0;
|
||||
MemoryCopy(&ptr_value, t->src, sizeof(ptr_value));
|
||||
U64 ptr_write_value = ((U64)((U8 *)ptr_value - (U8 *)ptr_ref_info->indexify_base)/t->type->direct->size);
|
||||
str8_serial_push_struct(scratch.arena, &strings, &ptr_write_value);
|
||||
}
|
||||
|
||||
// rjf: explicit identification -> descend to ID member at destination, write that
|
||||
else if(ptr_ref_info != 0 && ptr_ref_info->id_member.size != 0)
|
||||
// rjf: offsetification -> subtract base, write offsets
|
||||
else if(ptr_ref_info != 0 && ptr_ref_info->offsetify_base != 0)
|
||||
{
|
||||
Member *member = member_from_name(t->type->direct, ptr_ref_info->id_member);
|
||||
if(member != &member_nil)
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->type = member->type;
|
||||
task->ptr = ((U8 *)ptr_value) + member->value;
|
||||
task->count = 1;
|
||||
task->containing_type = t->type->direct;
|
||||
task->containing_ptr = ptr_value;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}
|
||||
U64 ptr_value = 0;
|
||||
MemoryCopy(&ptr_value, t->src, sizeof(ptr_value));
|
||||
U64 ptr_write_value = (U64)((U8 *)ptr_value - (U8 *)ptr_ref_info->offsetify_base);
|
||||
str8_serial_push_struct(scratch.arena, &strings, &ptr_write_value);
|
||||
}
|
||||
|
||||
// rjf: count-delimited pointers -> read count from member in containing type,
|
||||
// descend & write destination that way
|
||||
else if(t->type->count_delimiter_name.size != 0 && t->containing_type != 0)
|
||||
{
|
||||
Member *count_member = member_from_name(t->containing_type, t->type->count_delimiter_name);
|
||||
if(count_member != &member_nil)
|
||||
{
|
||||
U64 count = 0;
|
||||
MemoryCopy(&count, (U8 *)t->containing_ptr + count_member->value, count_member->type->size);
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->type = t->type->direct;
|
||||
task->ptr = ptr_value;
|
||||
task->count = count;
|
||||
task->containing_type = t->containing_type;
|
||||
task->containing_ptr = t->containing_ptr;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: any other nonzero pointer -> descend to pointer destination. trust usage code
|
||||
else if(ptr_value != 0)
|
||||
// rjf: size-by-member (pre-header): still potentially dependent on other members which
|
||||
// delimit our size, so push a new post-header task for pointer.
|
||||
else if(t->type->count_delimiter_name.size != 0 && !t->is_post_header)
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->type = t->type->direct;
|
||||
task->ptr = ptr_value;
|
||||
task->count = 1;
|
||||
task->type = t->type;
|
||||
task->count = t->count;
|
||||
task->src = t->src;
|
||||
task->containing_type = t->containing_type;
|
||||
task->containing_ptr = t->containing_ptr;
|
||||
task->is_post_header = 1;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}
|
||||
|
||||
// rjf: size-by-member (post-header): all flat parts of containing struct have been
|
||||
// iterated, so now we can read the size, & descend to new task to read pointer
|
||||
// destination contents
|
||||
else if(t->type->count_delimiter_name.size != 0 && t->is_post_header)
|
||||
{
|
||||
// rjf: determine count of this pointer
|
||||
U64 count = 0;
|
||||
{
|
||||
Member *count_member = member_from_name(t->containing_type, t->type->count_delimiter_name);
|
||||
MemoryCopy(&count, t->containing_ptr + count_member->value, count_member->type->size);
|
||||
}
|
||||
|
||||
// rjf: push task
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->type = t->type->direct;
|
||||
task->count = count;
|
||||
task->src = *(void **)t->src;
|
||||
task->containing_type = t->containing_type;
|
||||
task->containing_ptr = t->containing_ptr;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}
|
||||
}break;
|
||||
@@ -132,9 +130,175 @@ serialized_from_typed_data(Arena *arena, Type *type, void *ptr, TypeSerializePar
|
||||
case TypeKind_Array:
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->type = t->type->direct;
|
||||
task->ptr = t->ptr;
|
||||
task->count = t->type->count;
|
||||
task->type = t->type->direct;
|
||||
task->count = t->type->count;
|
||||
task->src = t->src;
|
||||
task->containing_type = t->containing_type;
|
||||
task->containing_ptr = t->containing_ptr;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}break;
|
||||
|
||||
//- rjf: struct -> descend to members
|
||||
case TypeKind_Struct:
|
||||
{
|
||||
U64 off = 0;
|
||||
for(U64 idx = 0; idx < t->count; idx += 1)
|
||||
{
|
||||
for(U64 member_idx = 0; member_idx < t->type->count; member_idx += 1)
|
||||
{
|
||||
if(t->type->members[member_idx].flags & MemberFlag_DoNotSerialize)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->type = t->type->members[member_idx].type;
|
||||
task->count = 1;
|
||||
task->src = t->src + t->type->members[member_idx].value;
|
||||
task->containing_type = t->type;
|
||||
task->containing_ptr = t->src;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
//- rjf: enum -> descend to basic type interpretation
|
||||
case TypeKind_Enum:
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->type = t->type->direct;
|
||||
task->count = t->count;
|
||||
task->src = t->src;
|
||||
task->containing_type = t->containing_type;
|
||||
task->containing_ptr = t->containing_ptr;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
String8 result = str8_serial_end(arena, &strings);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params)
|
||||
{
|
||||
String8 result = {0};
|
||||
result.size = type->size;
|
||||
result.str = push_array(arena, U8, result.size);
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
typedef struct Task Task;
|
||||
struct Task
|
||||
{
|
||||
Task *next;
|
||||
Type *type;
|
||||
U64 count;
|
||||
U8 *dst;
|
||||
Type *containing_type;
|
||||
U8 *containing_ptr;
|
||||
B32 is_post_header;
|
||||
};
|
||||
U64 read_off = 0;
|
||||
Task start_task = {0, type, 1, result.str};
|
||||
Task *first_task = &start_task;
|
||||
Task *last_task = first_task;
|
||||
for(Task *t = first_task; t != 0; t = t->next)
|
||||
{
|
||||
U8 *t_src = data.str + read_off;
|
||||
switch(t->type->kind)
|
||||
{
|
||||
//- rjf: leaf -> copy the data directly
|
||||
default:
|
||||
if(TypeKind_FirstLeaf <= t->type->kind && t->type->kind <= TypeKind_LastLeaf)
|
||||
{
|
||||
MemoryCopy(t->dst, t_src, t->type->size*t->count);
|
||||
read_off += t->type->size*t->count;
|
||||
}break;
|
||||
|
||||
//- rjf: pointers -> try to interpret/understand pointer & read/write, otherwise skip
|
||||
case TypeKind_Ptr:
|
||||
{
|
||||
// rjf: unpack info about this pointer
|
||||
TypeSerializePtrRefInfo *ptr_ref_info = 0;
|
||||
for(U64 idx = 0; idx < params->ptr_ref_infos_count; idx += 1)
|
||||
{
|
||||
if(params->ptr_ref_infos[idx].type == t->type->direct)
|
||||
{
|
||||
ptr_ref_info = ¶ms->ptr_ref_infos[idx];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: indexification -> add base, multiply direct size
|
||||
if(ptr_ref_info != 0 && ptr_ref_info->indexify_base != 0)
|
||||
{
|
||||
U64 ptr_value = 0;
|
||||
MemoryCopy(&ptr_value, t_src, sizeof(ptr_value));
|
||||
U64 ptr_write_value = (ptr_value + (U64)ptr_ref_info->indexify_base) * t->type->direct->size;
|
||||
MemoryCopy(t->dst, &ptr_write_value, sizeof(ptr_write_value));
|
||||
read_off += sizeof(ptr_value);
|
||||
}
|
||||
|
||||
// rjf: offsetification -> subtract base, write offsets
|
||||
else if(ptr_ref_info != 0 && ptr_ref_info->offsetify_base != 0)
|
||||
{
|
||||
U64 ptr_value = 0;
|
||||
MemoryCopy(&ptr_value, t_src, sizeof(ptr_value));
|
||||
U64 ptr_write_value = ptr_value + (U64)ptr_ref_info->offsetify_base;
|
||||
MemoryCopy(t->dst, &ptr_write_value, sizeof(ptr_write_value));
|
||||
read_off += sizeof(ptr_value);
|
||||
}
|
||||
|
||||
// rjf: size-by-member (pre-header): still potentially dependent on other members which
|
||||
// delimit our size, so push a new post-header task for pointer.
|
||||
else if(t->type->count_delimiter_name.size != 0 && !t->is_post_header)
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->type = t->type;
|
||||
task->count = t->count;
|
||||
task->dst = t->dst;
|
||||
task->containing_type = t->containing_type;
|
||||
task->containing_ptr = t->containing_ptr;
|
||||
task->is_post_header = 1;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}
|
||||
|
||||
// rjf: size-by-member (post-header): all flat parts of containing struct have been
|
||||
// iterated, so now we can read the size, & descend to new task to read pointer
|
||||
// destination contents
|
||||
else if(t->type->count_delimiter_name.size != 0 && t->is_post_header)
|
||||
{
|
||||
// rjf: determine count of this pointer
|
||||
U64 count = 0;
|
||||
{
|
||||
Member *count_member = member_from_name(t->containing_type, t->type->count_delimiter_name);
|
||||
MemoryCopy(&count, t->containing_ptr + count_member->value, count_member->type->size);
|
||||
}
|
||||
|
||||
// rjf: allocate buffer for pointer destination; write address into pointer value slot
|
||||
U64 ptr_dest_buffer_size = count*t->type->direct->size;
|
||||
U8 *ptr_dest_buffer = push_array(arena, U8, ptr_dest_buffer_size);
|
||||
MemoryCopy(t->dst, &ptr_dest_buffer, sizeof(ptr_dest_buffer));
|
||||
|
||||
// rjf: push task
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->type = t->type->direct;
|
||||
task->count = count;
|
||||
task->dst = ptr_dest_buffer;
|
||||
task->containing_type = t->containing_type;
|
||||
task->containing_ptr = t->containing_ptr;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}
|
||||
}break;
|
||||
|
||||
//- rjf: arrays -> descend to underlying type, + count
|
||||
case TypeKind_Array:
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->type = t->type->direct;
|
||||
task->count = t->type->count;
|
||||
task->dst = t->dst;
|
||||
task->containing_type = t->containing_type;
|
||||
task->containing_ptr = t->containing_ptr;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
@@ -153,10 +317,10 @@ serialized_from_typed_data(Arena *arena, Type *type, void *ptr, TypeSerializePar
|
||||
}
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->type = t->type->members[member_idx].type;
|
||||
task->ptr = (U8 *)t->ptr + t->type->size*idx + t->type->members[member_idx].value;
|
||||
task->count = 1;
|
||||
task->dst = t->dst + t->type->members[member_idx].value;
|
||||
task->containing_type = t->type;
|
||||
task->containing_ptr = t->ptr;
|
||||
task->containing_ptr = t->dst;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}
|
||||
}
|
||||
@@ -166,23 +330,16 @@ serialized_from_typed_data(Arena *arena, Type *type, void *ptr, TypeSerializePar
|
||||
case TypeKind_Enum:
|
||||
{
|
||||
Task *task = push_array(scratch.arena, Task, 1);
|
||||
task->type = t->type->direct;
|
||||
task->ptr = t->ptr;
|
||||
task->count = t->count;
|
||||
task->type = t->type->direct;
|
||||
task->count = t->count;
|
||||
task->dst = t->dst;
|
||||
task->containing_type = t->containing_type;
|
||||
task->containing_ptr = t->containing_ptr;
|
||||
SLLQueuePush(first_task, last_task, task);
|
||||
}break;
|
||||
}
|
||||
}
|
||||
scratch_end(scratch);
|
||||
}
|
||||
String8 result = str8_serial_end(scratch.arena, &strings);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal void *
|
||||
data_from_typed_serialized(Arena *arena, Type *type, String8 string, TypeSerializeParams *params)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
+47
-26
@@ -138,9 +138,10 @@ struct Type
|
||||
typedef struct TypeSerializePtrRefInfo TypeSerializePtrRefInfo;
|
||||
struct TypeSerializePtrRefInfo
|
||||
{
|
||||
Type *type; // pointers to this
|
||||
void *indexify_base; // can be indexified using this
|
||||
String8 id_member; // or ID'd via this member of the pointed-to-instance
|
||||
Type *type; // pointers to this
|
||||
void *indexify_base; // can be indexified using this
|
||||
void *offsetify_base; // can be offsetified using this
|
||||
void *nil_ptr; // is terminal if matching 0 or this
|
||||
};
|
||||
|
||||
typedef struct TypeSerializeParams TypeSerializeParams;
|
||||
@@ -150,42 +151,62 @@ struct TypeSerializeParams
|
||||
U64 ptr_ref_infos_count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Type Name -> Type Info
|
||||
|
||||
#define type(T) &(T##__type)
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Globals
|
||||
|
||||
read_only global Type type_leaves[] =
|
||||
read_only global Type type_nil = {TypeKind_Null, 0, 0, &type_nil};
|
||||
read_only global Type void__type = {TypeKind_Void, 0, 0, &type_nil, str8_lit_comp("void")};
|
||||
read_only global Type U8__type = {TypeKind_U8, 0, sizeof(U8), &type_nil, str8_lit_comp("U8")};
|
||||
read_only global Type U16__type = {TypeKind_U16, 0, sizeof(U16), &type_nil, str8_lit_comp("U16")};
|
||||
read_only global Type U32__type = {TypeKind_U32, 0, sizeof(U32), &type_nil, str8_lit_comp("U32")};
|
||||
read_only global Type U64__type = {TypeKind_U64, 0, sizeof(U64), &type_nil, str8_lit_comp("U64")};
|
||||
read_only global Type S8__type = {TypeKind_S8, 0, sizeof(S8), &type_nil, str8_lit_comp("S8")};
|
||||
read_only global Type S16__type = {TypeKind_S16, 0, sizeof(S16), &type_nil, str8_lit_comp("S16")};
|
||||
read_only global Type S32__type = {TypeKind_S32, 0, sizeof(S32), &type_nil, str8_lit_comp("S32")};
|
||||
read_only global Type S64__type = {TypeKind_S64, 0, sizeof(S64), &type_nil, str8_lit_comp("S64")};
|
||||
read_only global Type B8__type = {TypeKind_B8, 0, sizeof(B8), &type_nil, str8_lit_comp("B8")};
|
||||
read_only global Type B16__type = {TypeKind_B16, 0, sizeof(B16), &type_nil, str8_lit_comp("B16")};
|
||||
read_only global Type B32__type = {TypeKind_B32, 0, sizeof(B32), &type_nil, str8_lit_comp("B32")};
|
||||
read_only global Type B64__type = {TypeKind_B64, 0, sizeof(B64), &type_nil, str8_lit_comp("B64")};
|
||||
read_only global Type F32__type = {TypeKind_F32, 0, sizeof(F32), &type_nil, str8_lit_comp("F32")};
|
||||
read_only global Type F64__type = {TypeKind_F64, 0, sizeof(F64), &type_nil, str8_lit_comp("F64")};
|
||||
read_only global Type *type_leaves[] =
|
||||
{
|
||||
{TypeKind_Null, 0, 0, &type_leaves[0], str8_lit_comp("null")},
|
||||
{TypeKind_Void, 0, 0, &type_leaves[0], str8_lit_comp("void")},
|
||||
{TypeKind_U8, 0, sizeof(U8), &type_leaves[0], str8_lit_comp("U8")},
|
||||
{TypeKind_U16, 0, sizeof(U16), &type_leaves[0], str8_lit_comp("U16")},
|
||||
{TypeKind_U32, 0, sizeof(U32), &type_leaves[0], str8_lit_comp("U32")},
|
||||
{TypeKind_U64, 0, sizeof(U64), &type_leaves[0], str8_lit_comp("U64")},
|
||||
{TypeKind_S8, 0, sizeof(S8), &type_leaves[0], str8_lit_comp("S8")},
|
||||
{TypeKind_S16, 0, sizeof(S16), &type_leaves[0], str8_lit_comp("S16")},
|
||||
{TypeKind_S32, 0, sizeof(S32), &type_leaves[0], str8_lit_comp("S32")},
|
||||
{TypeKind_S64, 0, sizeof(S64), &type_leaves[0], str8_lit_comp("S64")},
|
||||
{TypeKind_B8, 0, sizeof(B8), &type_leaves[0], str8_lit_comp("B8")},
|
||||
{TypeKind_B16, 0, sizeof(B16), &type_leaves[0], str8_lit_comp("B16")},
|
||||
{TypeKind_B32, 0, sizeof(B32), &type_leaves[0], str8_lit_comp("B32")},
|
||||
{TypeKind_B64, 0, sizeof(B64), &type_leaves[0], str8_lit_comp("B64")},
|
||||
{TypeKind_F32, 0, sizeof(F32), &type_leaves[0], str8_lit_comp("F32")},
|
||||
{TypeKind_F64, 0, sizeof(F64), &type_leaves[0], str8_lit_comp("F64")},
|
||||
&type_nil,
|
||||
type(void),
|
||||
type(U8),
|
||||
type(U16),
|
||||
type(U32),
|
||||
type(U64),
|
||||
type(S8),
|
||||
type(S16),
|
||||
type(S32),
|
||||
type(S64),
|
||||
type(B8),
|
||||
type(B16),
|
||||
type(B32),
|
||||
type(B64),
|
||||
type(F32),
|
||||
type(F64),
|
||||
};
|
||||
read_only global Member member_nil = {{0}, &type_leaves[0]};
|
||||
read_only global Member member_nil = {{0}, &type_nil};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Type Info Lookups
|
||||
|
||||
#define type(T) &(T##__type)
|
||||
internal Member *member_from_name(Type *type, String8 name);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Type Info * Instance Operations
|
||||
|
||||
internal String8 serialized_from_typed_data(Arena *arena, Type *type, void *ptr, TypeSerializeParams *params);
|
||||
internal void *data_from_typed_serialized(Arena *arena, Type *type, String8 string, TypeSerializeParams *params);
|
||||
#define serialized_from_struct(arena, T, ptr, ...) serialized_from_typed_data((arena), type(T), (ptr), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__})
|
||||
#define struct_from_serialized(arena, T, string, ...) (T *)data_from_typed_serialized((arena), type(T), (string), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__})
|
||||
internal String8 serialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params);
|
||||
internal String8 deserialized_from_typed_data(Arena *arena, Type *type, String8 data, TypeSerializeParams *params);
|
||||
#define serialized_from_struct(arena, T, ptr, ...) serialized_from_typed_data((arena), type(T), str8_struct(ptr), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__})
|
||||
#define struct_from_serialized(arena, T, string, ...) (T *)deserialized_from_typed_data((arena), type(T), (string), &(TypeSerializeParams){.ptr_ref_infos = 0, __VA_ARGS__}).str
|
||||
|
||||
#endif // BASE_META_H
|
||||
|
||||
+31
-28
@@ -54,12 +54,12 @@ struct FooBar
|
||||
|
||||
//-
|
||||
|
||||
Type String8__str_ptr_type = {TypeKind_Ptr, 0, sizeof(void *), &type_leaves[TypeKind_U8], {0}, str8_lit_comp("size")};
|
||||
Type String8__str_ptr_type = {TypeKind_Ptr, 0, sizeof(void *), type(U8), {0}, str8_lit_comp("size")};
|
||||
|
||||
Member String8__members[] =
|
||||
{
|
||||
{str8_lit_comp("str"), &String8__str_ptr_type, OffsetOf(String8, str)},
|
||||
{str8_lit_comp("size"), &type_leaves[TypeKind_U64], OffsetOf(String8, size)},
|
||||
{str8_lit_comp("str"), &String8__str_ptr_type, OffsetOf(String8, str)},
|
||||
{str8_lit_comp("size"), type(U64), OffsetOf(String8, size)},
|
||||
};
|
||||
|
||||
Type String8__type =
|
||||
@@ -67,7 +67,7 @@ Type String8__type =
|
||||
TypeKind_Struct,
|
||||
0,
|
||||
sizeof(String8),
|
||||
&type_leaves[0],
|
||||
&type_nil,
|
||||
str8_lit_comp("String8"),
|
||||
{0},
|
||||
ArrayCount(String8__members),
|
||||
@@ -90,7 +90,7 @@ Type String8Node__type =
|
||||
TypeKind_Struct,
|
||||
0,
|
||||
sizeof(String8Node),
|
||||
&type_leaves[0],
|
||||
&type_nil,
|
||||
str8_lit_comp("String8Node"),
|
||||
{0},
|
||||
ArrayCount(String8Node__members),
|
||||
@@ -103,8 +103,8 @@ Member String8List__members[] =
|
||||
{
|
||||
{str8_lit_comp("first"), &String8Node__ptr_type, OffsetOf(String8List, first)},
|
||||
{str8_lit_comp("last"), &String8Node__ptr_type, OffsetOf(String8List, last), MemberFlag_DoNotSerialize},
|
||||
{str8_lit_comp("node_count"), &type_leaves[TypeKind_U64], OffsetOf(String8List, node_count)},
|
||||
{str8_lit_comp("total_size"), &type_leaves[TypeKind_U64], OffsetOf(String8List, total_size)},
|
||||
{str8_lit_comp("node_count"), type(U64), OffsetOf(String8List, node_count)},
|
||||
{str8_lit_comp("total_size"), type(U64), OffsetOf(String8List, total_size)},
|
||||
};
|
||||
|
||||
Type String8List__type =
|
||||
@@ -112,7 +112,7 @@ Type String8List__type =
|
||||
TypeKind_Struct,
|
||||
0,
|
||||
sizeof(String8List),
|
||||
&type_leaves[0],
|
||||
&type_nil,
|
||||
str8_lit_comp("String8List"),
|
||||
{0},
|
||||
ArrayCount(String8List__members),
|
||||
@@ -123,10 +123,10 @@ Type String8List__type =
|
||||
|
||||
Member FooBar__members[] =
|
||||
{
|
||||
{str8_lit_comp("x"), &type_leaves[TypeKind_U64], OffsetOf(FooBar, x)},
|
||||
{str8_lit_comp("y"), &type_leaves[TypeKind_U64], OffsetOf(FooBar, y)},
|
||||
{str8_lit_comp("z"), &type_leaves[TypeKind_U64], OffsetOf(FooBar, z)},
|
||||
{str8_lit_comp("name"), type(String8), OffsetOf(FooBar, name)},
|
||||
{str8_lit_comp("x"), type(U64), OffsetOf(FooBar, x)},
|
||||
{str8_lit_comp("y"), type(U64), OffsetOf(FooBar, y)},
|
||||
{str8_lit_comp("z"), type(U64), OffsetOf(FooBar, z)},
|
||||
{str8_lit_comp("name"), type(String8), OffsetOf(FooBar, name)},
|
||||
};
|
||||
|
||||
Type FooBar__type =
|
||||
@@ -134,7 +134,7 @@ Type FooBar__type =
|
||||
TypeKind_Struct,
|
||||
0,
|
||||
sizeof(FooBar),
|
||||
&type_leaves[0],
|
||||
&type_nil,
|
||||
str8_lit_comp("FooBar"),
|
||||
{0},
|
||||
ArrayCount(FooBar__members),
|
||||
@@ -146,23 +146,26 @@ entry_point(CmdLine *cmdline)
|
||||
{
|
||||
Arena *arena = arena_alloc();
|
||||
|
||||
String8List strs = {0};
|
||||
str8_list_pushf(arena, &strs, "foobar: %i", 123);
|
||||
str8_list_pushf(arena, &strs, "xyzxyzxyz");
|
||||
str8_list_pushf(arena, &strs, "abc abc abc");
|
||||
str8_list_pushf(arena, &strs, "123");
|
||||
str8_list_pushf(arena, &strs, "456");
|
||||
str8_list_pushf(arena, &strs, "789");
|
||||
str8_list_pushf(arena, &strs, "111");
|
||||
str8_list_pushf(arena, &strs, "222");
|
||||
str8_list_pushf(arena, &strs, "333");
|
||||
String8 strs_serialized = serialized_from_struct(arena, String8List, &strs);
|
||||
FooBar foobar_in = {1, 2, 3, str8_lit("foobar 123 hello world")};
|
||||
String8 foobar_srlz = serialized_from_struct(arena, FooBar, &foobar_in);
|
||||
FooBar foobar_out = *struct_from_serialized(arena, FooBar, foobar_srlz);
|
||||
|
||||
String8 test_name = str8_lit("foobar 123");
|
||||
String8 test_name_serialized = serialized_from_struct(arena, String8, &test_name);
|
||||
String8List strs_in = {0};
|
||||
str8_list_pushf(arena, &strs_in, "foobar: %i", 123);
|
||||
str8_list_pushf(arena, &strs_in, "xyzxyzxyz");
|
||||
str8_list_pushf(arena, &strs_in, "abc abc abc");
|
||||
str8_list_pushf(arena, &strs_in, "123");
|
||||
str8_list_pushf(arena, &strs_in, "456");
|
||||
str8_list_pushf(arena, &strs_in, "789");
|
||||
str8_list_pushf(arena, &strs_in, "111");
|
||||
str8_list_pushf(arena, &strs_in, "222");
|
||||
str8_list_pushf(arena, &strs_in, "333");
|
||||
String8 strs_serialized = serialized_from_struct(arena, String8List, &strs_in);
|
||||
String8List strs_out = *struct_from_serialized(arena, String8List, strs_serialized);
|
||||
|
||||
FooBar foobar = {1, 2, 3, str8_lit("foobar 123 hello world")};
|
||||
String8 foobar_serialized = serialized_from_struct(arena, FooBar, &foobar);
|
||||
String8 test_name_in = str8_lit("foobar 123");
|
||||
String8 test_name_srlz = serialized_from_struct(arena, String8, &test_name_in);
|
||||
String8 test_name_out = *struct_from_serialized(arena, String8, test_name_srlz);
|
||||
|
||||
int x = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user