Files
raddebugger/src/lib_rdi_make/rdi_make.c
T

2079 lines
68 KiB
C

// Copyright (c) Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
////////////////////////////////
//~ rjf: API Implementation Helper Macros
#define RDIM_IdxedChunkListPush(arena, list, chunk_type, element_type, cap_value, result, ...) \
element_type *result = 0;\
do\
{\
chunk_type *n = list->last;\
if(n == 0 || n->count >= n->cap)\
{\
n = rdim_push_array(arena, chunk_type, 1);\
n->cap = cap_value;\
n->base_idx = list->total_count;\
__VA_ARGS__;\
n->v = rdim_push_array_no_zero(arena, element_type, n->cap);\
RDIM_SLLQueuePush(list->first, list->last, n);\
list->chunk_count += 1;\
}\
result = &n->v[n->count];\
result->chunk = n;\
n->count += 1;\
list->total_count += 1;\
}while(0)
#define RDIM_IdxedChunkListElementGetIdx(ptr, result) \
RDI_U64 idx = 0;\
if(ptr != 0 && ptr->chunk != 0)\
{\
idx = ptr->chunk->base_idx + (ptr - ptr->chunk->v) + 1;\
}
#define RDIM_IdxedChunkListConcatInPlace(chunk_type, dst, to_push, ...) \
for(chunk_type *n = to_push->first; n != 0; n = n->next)\
{\
n->base_idx += dst->total_count;\
}\
if(dst->last != 0 && to_push->first != 0)\
{\
dst->last->next = to_push->first;\
dst->last = to_push->last;\
dst->chunk_count += to_push->chunk_count;\
dst->total_count += to_push->total_count;\
__VA_ARGS__;\
}\
else if(dst->first == 0)\
{\
rdim_memcpy_struct(dst, to_push);\
}\
rdim_memzero_struct(to_push);
////////////////////////////////
//~ rjf: Basic Helpers
//- rjf: memory set
#if !defined(RDIM_MEMSET_OVERRIDE)
RDI_PROC void *
rdim_memset_fallback(void *dst, RDI_U8 c, RDI_U64 size)
{
for(RDI_U64 idx = 0; idx < size; idx += 1)
{
((RDI_U8 *)dst)[idx] = c;
}
return dst;
}
#endif
#if !defined(RDIM_MEMCPY_OVERRIDE)
RDI_PROC void *
rdim_memcpy_fallback(void *dst, void *src, RDI_U64 size)
{
for(RDI_U64 idx = 0; idx < size; idx += 1)
{
((RDI_U8 *)dst)[idx] = ((RDI_U8 *)src)[idx];
}
return dst;
}
#endif
//- rjf: arenas
#if !defined (RDIM_ARENA_OVERRIDE)
RDI_PROC RDIM_Arena *
rdim_arena_alloc_fallback(void)
{
RDIM_Arena *arena = 0;
// TODO(rjf)
return arena;
}
RDI_PROC void
rdim_arena_release_fallback(RDIM_Arena *arena)
{
// TODO(rjf)
}
RDI_PROC RDI_U64
rdim_arena_pos_fallback(RDIM_Arena *arena)
{
// TODO(rjf)
return 0;
}
RDI_PROC void *
rdim_arena_push_fallback(RDIM_Arena *arena, RDI_U64 size, RDI_U64 align, RDI_U32 zero)
{
// TODO(rjf)
return 0;
}
RDI_PROC void
rdim_arena_pop_to_fallback(RDIM_Arena *arena, RDI_U64 pos)
{
// TODO(rjf)
}
#endif
//- rjf: thread-local scratch arenas
#if !defined (RDIM_SCRATCH_OVERRIDE)
static RDIM_THREAD_LOCAL RDIM_Arena *rdim_thread_scratches[2];
RDI_PROC RDIM_Temp
rdim_scratch_begin_fallback(RDIM_Arena **conflicts, RDI_U64 conflicts_count)
{
if(rdim_thread_scratches[0] == 0)
{
rdim_thread_scratches[0] = rdim_arena_alloc();
rdim_thread_scratches[1] = rdim_arena_alloc();
}
RDIM_Arena *arena = 0;
for(RDI_U64 scratch_idx = 0;
scratch_idx < sizeof(rdim_thread_scratches)/sizeof(rdim_thread_scratches[0]);
scratch_idx += 1)
{
RDI_S32 scratch_conflicts = 0;
for(RDI_U64 conflict_idx = 0; conflict_idx < conflicts_count; conflict_idx += 1)
{
if(conflicts[conflict_idx] == rdim_thread_scratches[scratch_idx])
{
scratch_conflicts = 1;
break;
}
}
if(!scratch_conflicts)
{
arena = rdim_thread_scratches[scratch_idx];
}
}
RDIM_Temp temp;
temp.arena = arena;
temp.pos = rdim_arena_pos(arena);
return temp;
}
RDI_PROC void
rdim_scratch_end_fallback(RDIM_Temp temp)
{
rdim_arena_pop_to(temp.arena, temp.pos);
}
#endif
//- rjf: strings
RDI_PROC RDIM_String8
rdim_str8(RDI_U8 *str, RDI_U64 size)
{
RDIM_String8 result;
result.RDIM_String8_BaseMember = str;
result.RDIM_String8_SizeMember = size;
return result;
}
RDI_PROC RDIM_String8
rdim_str8_copy(RDIM_Arena *arena, RDIM_String8 src)
{
RDIM_String8 dst;
dst.RDIM_String8_SizeMember = src.RDIM_String8_SizeMember;
dst.RDIM_String8_BaseMember = rdim_push_array_no_zero(arena, RDI_U8, dst.RDIM_String8_SizeMember+1);
rdim_memcpy(dst.RDIM_String8_BaseMember, src.RDIM_String8_BaseMember, src.RDIM_String8_SizeMember);
dst.RDIM_String8_BaseMember[dst.RDIM_String8_SizeMember] = 0;
return dst;
}
RDI_PROC RDIM_String8
rdim_str8f(RDIM_Arena *arena, char *fmt, ...)
{
va_list args;
va_start(args, fmt);
RDIM_String8 result = rdim_str8fv(arena, fmt, args);
va_end(args);
return(result);
}
RDI_PROC RDIM_String8
rdim_str8fv(RDIM_Arena *arena, char *fmt, va_list args)
{
va_list args2;
va_copy(args2, args);
RDI_U32 needed_bytes = rdim_vsnprintf(0, 0, fmt, args) + 1;
RDIM_String8 result = {0};
result.RDIM_String8_BaseMember = rdim_push_array_no_zero(arena, RDI_U8, needed_bytes);
result.RDIM_String8_SizeMember = rdim_vsnprintf((char*)result.str, needed_bytes, fmt, args2);
result.RDIM_String8_BaseMember[result.RDIM_String8_SizeMember] = 0;
va_end(args2);
return(result);
}
RDI_PROC RDI_S32
rdim_str8_match(RDIM_String8 a, RDIM_String8 b, RDIM_StringMatchFlags flags)
{
RDI_S32 result = 0;
if(a.RDIM_String8_SizeMember == b.RDIM_String8_SizeMember)
{
RDI_S32 case_insensitive = (flags & RDIM_StringMatchFlag_CaseInsensitive);
RDI_U64 size = a.RDIM_String8_SizeMember;
result = 1;
for(RDI_U64 idx = 0; idx < size; idx += 1)
{
RDI_U8 at = a.RDIM_String8_BaseMember[idx];
RDI_U8 bt = b.RDIM_String8_BaseMember[idx];
if(case_insensitive)
{
at = ('a' <= at && at <= 'z') ? at-('a'-'A') : at;
bt = ('a' <= bt && bt <= 'z') ? bt-('a'-'A') : bt;
}
if(at != bt)
{
result = 0;
break;
}
}
}
return result;
}
RDI_PROC RDIM_String8
rdim_lower_from_str8(RDIM_Arena *arena, RDIM_String8 string)
{
RDIM_String8 result = rdim_str8_copy(arena, string);
for(RDI_U64 idx = 0; idx < result.RDIM_String8_SizeMember; idx += 1)
{
RDI_U8 byte = result.RDIM_String8_BaseMember[idx];
if('A' <= byte && byte <= 'Z')
{
result.RDIM_String8_BaseMember[idx] += ('a' - 'A');
}
}
return result;
}
//- rjf: string lists
RDI_PROC void
rdim_str8_list_push(RDIM_Arena *arena, RDIM_String8List *list, RDIM_String8 string)
{
RDIM_String8Node *n = rdim_push_array(arena, RDIM_String8Node, 1);
n->RDIM_String8Node_StringMember = string;
RDIM_SLLQueuePush_N(list->RDIM_String8List_FirstMember, list->RDIM_String8List_LastMember, n, RDIM_String8Node_NextPtrMember);
list->RDIM_String8List_NodeCountMember += 1;
list->RDIM_String8List_TotalSizeMember += string.RDIM_String8_SizeMember;
}
RDI_PROC void
rdim_str8_list_push_front(RDIM_Arena *arena, RDIM_String8List *list, RDIM_String8 string)
{
RDIM_String8Node *n = rdim_push_array(arena, RDIM_String8Node, 1);
n->RDIM_String8Node_StringMember = string;
RDIM_SLLQueuePushFront_N(list->RDIM_String8List_FirstMember, list->RDIM_String8List_LastMember, n, RDIM_String8Node_NextPtrMember);
list->RDIM_String8List_NodeCountMember += 1;
list->RDIM_String8List_TotalSizeMember += string.RDIM_String8_SizeMember;
}
RDI_PROC void
rdim_str8_list_push_align(RDIM_Arena *arena, RDIM_String8List *list, RDI_U64 align)
{
RDI_U64 total_size_pre_align = list->total_size;
RDI_U64 total_size_post_align = (total_size_pre_align + (align-1))&(~(align-1));
RDI_U64 needed_size = total_size_post_align - total_size_pre_align;
if(needed_size != 0)
{
RDI_U8 *padding = rdim_push_array(arena, RDI_U8, needed_size);
rdim_str8_list_push(arena, list, rdim_str8(padding, needed_size));
}
}
RDI_PROC RDIM_String8
rdim_str8_list_join(RDIM_Arena *arena, RDIM_String8List *list, RDIM_String8 sep)
{
RDIM_String8 result;
rdim_memzero_struct(&result);
RDI_U64 sep_count = (list->RDIM_String8List_NodeCountMember > 1) ? (list->RDIM_String8List_NodeCountMember-1) : 0;
result.RDIM_String8_SizeMember = list->RDIM_String8List_TotalSizeMember+sep_count*sep.RDIM_String8_SizeMember;
result.RDIM_String8_BaseMember = rdim_push_array_no_zero(arena, RDI_U8, result.RDIM_String8_SizeMember+1);
RDI_U64 off = 0;
for(RDIM_String8Node *node = list->RDIM_String8List_FirstMember;
node != 0;
node = node->RDIM_String8Node_NextPtrMember)
{
rdim_memcpy((RDI_U8*)result.RDIM_String8_BaseMember+off,
node->RDIM_String8Node_StringMember.RDIM_String8_BaseMember,
node->RDIM_String8Node_StringMember.RDIM_String8_SizeMember);
off += node->RDIM_String8Node_StringMember.RDIM_String8_SizeMember;
if(sep.RDIM_String8_SizeMember != 0 && node->RDIM_String8Node_NextPtrMember != 0)
{
rdim_memcpy((RDI_U8*)result.RDIM_String8_BaseMember+off,
sep.RDIM_String8_BaseMember,
sep.RDIM_String8_SizeMember);
off += sep.RDIM_String8_SizeMember;
}
}
result.RDIM_String8_BaseMember[off] = 0;
return result;
}
//- rjf: sortable range sorting
RDI_PROC RSFORCEINLINE int
rdim_sort_key_is_before(void *l, void *r)
{
return ((RDIM_SortKey *)l)->key < ((RDIM_SortKey *)r)->key;
}
RDI_PROC RDIM_SortKey *
rdim_sort_key_array(RDIM_Arena *arena, RDIM_SortKey *keys, RDI_U64 count)
{
// This sort is designed to take advantage of lots of pre-existing sorted ranges.
// Most line info is already sorted or close to already sorted.
// Similarly most vmap data has lots of pre-sorted ranges. etc. etc.
// Also - this sort should be a "stable" sort. In the use case of sorting vmap
// ranges, we want to be able to rely on order, so it needs to be preserved here.
RDIM_Temp scratch = rdim_scratch_begin(&arena, 1);
RDIM_SortKey *result = 0;
if(count <= 1)
{
result = keys;
}
else
{
RDIM_OrderedRange *ranges_first = 0;
RDIM_OrderedRange *ranges_last = 0;
RDI_U64 range_count = 0;
{
RDI_U64 pos = 0;
for(;pos < count;)
{
// identify ordered range
RDI_U64 first = pos;
RDI_U64 opl = pos + 1;
for(; opl < count && keys[opl - 1].key <= keys[opl].key; opl += 1);
// generate an ordered range node
RDIM_OrderedRange *new_range = rdim_push_array(rdim_temp_arena(scratch), RDIM_OrderedRange, 1);
RDIM_SLLQueuePush(ranges_first, ranges_last, new_range);
range_count += 1;
new_range->first = first;
new_range->opl = opl;
// update pos
pos = opl;
}
}
if(range_count == 1)
{
result = keys;
}
else
{
RDIM_SortKey *keys_swap = rdim_push_array_no_zero(arena, RDIM_SortKey, count);
RDIM_SortKey *src = keys;
RDIM_SortKey *dst = keys_swap;
RDIM_OrderedRange *src_ranges = ranges_first;
RDIM_OrderedRange *dst_ranges = 0;
RDIM_OrderedRange *dst_ranges_last = 0;
for(;;)
{
// begin a pass
for(;;)
{
// end pass when out of ranges
if(src_ranges == 0)
{
break;
}
// get first range
RDIM_OrderedRange *range1 = src_ranges;
RDIM_SLLStackPop(src_ranges);
// if this range is the whole array, we are done
if(range1->first == 0 && range1->opl == count)
{
result = src;
goto sort_done;
}
// if there is not a second range, save this range for next time and end this pass
if(src_ranges == 0)
{
RDI_U64 first = range1->first;
rdim_memcpy(dst + first, src + first, sizeof(*src)*(range1->opl - first));
RDIM_SLLQueuePush(dst_ranges, dst_ranges_last, range1);
break;
}
// get second range
RDIM_OrderedRange *range2 = src_ranges;
RDIM_SLLStackPop(src_ranges);
#if 0
rdim_assert(range1->opl == range2->first);
#endif
// merge these ranges
RDI_U64 jd = range1->first;
RDI_U64 j1 = range1->first;
RDI_U64 j1_opl = range1->opl;
RDI_U64 j2 = range2->first;
RDI_U64 j2_opl = range2->opl;
for(;;)
{
if(src[j1].key <= src[j2].key)
{
rdim_memcpy(dst + jd, src + j1, sizeof(*src));
j1 += 1;
jd += 1;
if(j1 >= j1_opl)
{
break;
}
}
else
{
rdim_memcpy(dst + jd, src + j2, sizeof(*src));
j2 += 1;
jd += 1;
if(j2 >= j2_opl)
{
break;
}
}
}
if(j1 < j1_opl)
{
rdim_memcpy(dst + jd, src + j1, sizeof(*src)*(j1_opl - j1));
}
else
{
rdim_memcpy(dst + jd, src + j2, sizeof(*src)*(j2_opl - j2));
}
// save this as one range
range1->opl = range2->opl;
SLLQueuePush(dst_ranges, dst_ranges_last, range1);
}
// end pass by swapping buffers and range nodes
{
RDIM_SortKey *temp = src;
src = dst;
dst = temp;
}
src_ranges = dst_ranges;
dst_ranges = 0;
dst_ranges_last = 0;
}
}
}
sort_done:;
#if 0
// assert sortedness
for(RDI_U64 i = 1; i < count; i += 1)
{
rdim_assert(result[i - 1].key <= result[i].key);
}
#endif
rdim_scratch_end(scratch);
return result;
}
//- rjf: rng1u64 list
RDI_PROC void
rdim_rng1u64_list_push(RDIM_Arena *arena, RDIM_Rng1U64List *list, RDIM_Rng1U64 r)
{
RDIM_Rng1U64Node *n = rdim_push_array(arena, RDIM_Rng1U64Node, 1);
n->v = r;
RDIM_SLLQueuePush(list->first, list->last, n);
list->count += 1;
if(list->count == 1 || r.min < list->min)
{
list->min = r.min;
}
}
RDI_PROC void
rdim_rng1u64_chunk_list_push(RDIM_Arena *arena, RDIM_Rng1U64ChunkList *list, RDI_U64 chunk_cap, RDIM_Rng1U64 r)
{
RDIM_Rng1U64ChunkNode *n = list->last;
if(n == 0 || n->count >= n->cap)
{
n = rdim_push_array(arena, RDIM_Rng1U64ChunkNode, 1);
RDIM_SLLQueuePush(list->first, list->last, n);
n->cap = chunk_cap;
n->v = rdim_push_array_no_zero(arena, RDIM_Rng1U64, n->cap);
list->chunk_count += 1;
}
n->v[n->count] = r;
n->count += 1;
list->total_count += 1;
if(list->total_count == 1 || r.min < list->min)
{
list->min = r.min;
}
}
////////////////////////////////
//~ rjf: [Building] Data Model
RDI_PROC RDI_TypeKind
rdim_short_type_kind_from_data_model(RDIM_DataModel data_model)
{
RDI_TypeKind result = RDI_TypeKind_NULL;
switch((RDIM_DataModelEnum)data_model)
{
case RDIM_DataModel_Null:{}break;
case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_S16;}break;
case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_S16;}break;
case RDIM_DataModel_LP64 :{result = RDI_TypeKind_S16;}break;
case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_S16;}break;
case RDIM_DataModel_SILP64:{result = RDI_TypeKind_S64;}break;
}
return result;
}
RDI_PROC RDI_TypeKind
rdim_unsigned_short_type_kind_from_data_model(RDIM_DataModel data_model)
{
RDI_TypeKind result = RDI_TypeKind_NULL;
switch((RDIM_DataModelEnum)data_model)
{
case RDIM_DataModel_Null:{}break;
case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_U16;}break;
case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_U16;}break;
case RDIM_DataModel_LP64 :{result = RDI_TypeKind_U16;}break;
case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_U16;}break;
case RDIM_DataModel_SILP64:{result = RDI_TypeKind_U64;}break;
}
return result;
}
RDI_PROC RDI_TypeKind
rdim_int_type_from_data_model(RDIM_DataModel data_model)
{
RDI_TypeKind result = RDI_TypeKind_NULL;
switch((RDIM_DataModelEnum)data_model)
{
case RDIM_DataModel_Null:{}break;
case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_S32;}break;
case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_S32;}break;
case RDIM_DataModel_LP64 :{result = RDI_TypeKind_S32;}break;
case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_S64;}break;
case RDIM_DataModel_SILP64:{result = RDI_TypeKind_S64;}break;
}
return result;
}
RDI_PROC RDI_TypeKind
rdim_unsigned_int_type_from_data_model(RDIM_DataModel data_model)
{
RDI_TypeKind result = RDI_TypeKind_NULL;
switch((RDIM_DataModelEnum)data_model)
{
case RDIM_DataModel_Null:{}break;
case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_U32;}break;
case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_U32;}break;
case RDIM_DataModel_LP64 :{result = RDI_TypeKind_U32;}break;
case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_U64;}break;
case RDIM_DataModel_SILP64:{result = RDI_TypeKind_U64;}break;
}
return result;
}
RDI_PROC RDI_TypeKind
rdim_long_type_kind_from_data_model(RDIM_DataModel data_model)
{
RDI_TypeKind result = RDI_TypeKind_NULL;
switch((RDIM_DataModelEnum)data_model)
{
case RDIM_DataModel_Null:{}break;
case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_S32;}break;
case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_S32;}break;
case RDIM_DataModel_LP64 :{result = RDI_TypeKind_S64;}break;
case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_S64;}break;
case RDIM_DataModel_SILP64:{result = RDI_TypeKind_S64;}break;
}
return result;
}
RDI_PROC RDI_TypeKind
rdim_unsigned_long_type_kind_from_data_model(RDIM_DataModel data_model)
{
RDI_TypeKind result = RDI_TypeKind_NULL;
switch((RDIM_DataModelEnum)data_model)
{
case RDIM_DataModel_Null:{}break;
case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_U32;}break;
case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_U32;}break;
case RDIM_DataModel_LP64 :{result = RDI_TypeKind_U64;}break;
case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_U64;}break;
case RDIM_DataModel_SILP64:{result = RDI_TypeKind_U64;}break;
}
return result;
}
RDI_PROC RDI_TypeKind
rdim_long_long_type_kind_from_data_model(RDIM_DataModel data_model)
{
RDI_TypeKind result = RDI_TypeKind_NULL;
switch((RDIM_DataModelEnum)data_model)
{
case RDIM_DataModel_Null:{}break;
case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_S64;}break;
case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_S64;}break;
case RDIM_DataModel_LP64 :{result = RDI_TypeKind_S64;}break;
case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_S64;}break;
case RDIM_DataModel_SILP64:{result = RDI_TypeKind_S64;}break;
}
return result;
}
RDI_PROC RDI_TypeKind
rdim_unsigned_long_long_type_kind_from_data_model(RDIM_DataModel data_model)
{
RDI_TypeKind result = RDI_TypeKind_NULL;
switch((RDIM_DataModelEnum)data_model)
{
case RDIM_DataModel_Null:{}break;
case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_U64;}break;
case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_U64;}break;
case RDIM_DataModel_LP64 :{result = RDI_TypeKind_U64;}break;
case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_U64;}break;
case RDIM_DataModel_SILP64:{result = RDI_TypeKind_U64;}break;
}
return result;
}
RDI_PROC RDI_TypeKind
rdim_pointer_size_t_type_kind_from_data_model(RDIM_DataModel data_model)
{
RDI_TypeKind result = RDI_TypeKind_NULL;
switch((RDIM_DataModelEnum)data_model)
{
case RDIM_DataModel_Null:{}break;
case RDIM_DataModel_ILP32 :{result = RDI_TypeKind_U32;}break;
case RDIM_DataModel_LLP64 :{result = RDI_TypeKind_U64;}break;
case RDIM_DataModel_LP64 :{result = RDI_TypeKind_U64;}break;
case RDIM_DataModel_ILP64 :{result = RDI_TypeKind_U64;}break;
case RDIM_DataModel_SILP64:{result = RDI_TypeKind_U64;}break;
}
return result;
}
////////////////////////////////
//~ rjf: [Building] Binary Section List Building
RDI_PROC RDIM_BinarySection *
rdim_binary_section_list_push(RDIM_Arena *arena, RDIM_BinarySectionList *list)
{
RDIM_BinarySectionNode *n = rdim_push_array(arena, RDIM_BinarySectionNode, 1);
RDIM_SLLQueuePush(list->first, list->last, n);
list->count += 1;
RDIM_BinarySection *result = &n->v;
return result;
}
////////////////////////////////
//~ rjf: [Building] Source File Info Building
RDI_PROC RDIM_SrcFile *
rdim_src_file_chunk_list_push(RDIM_Arena *arena, RDIM_SrcFileChunkList *list, RDI_U64 cap)
{
RDIM_IdxedChunkListPush(arena, list, RDIM_SrcFileChunkNode, RDIM_SrcFile, cap, result);
return result;
}
RDI_PROC RDI_U64
rdim_idx_from_src_file(RDIM_SrcFile *src_file)
{
RDIM_IdxedChunkListElementGetIdx(src_file, idx);
return idx;
}
RDI_PROC void
rdim_src_file_chunk_list_concat_in_place(RDIM_SrcFileChunkList *dst, RDIM_SrcFileChunkList *to_push)
{
RDIM_IdxedChunkListConcatInPlace(RDIM_SrcFileChunkNode, dst, to_push,
dst->source_line_map_count += to_push->source_line_map_count,
dst->total_line_count += to_push->total_line_count);
}
RDI_PROC void
rdim_src_file_push_line_sequence(RDIM_Arena *arena, RDIM_SrcFileChunkList *src_files, RDIM_SrcFile *src_file, RDIM_LineSequence *seq)
{
if(src_file->first_line_map_fragment == 0)
{
src_files->source_line_map_count += 1;
}
RDIM_SrcFileLineMapFragment *fragment = rdim_push_array(arena, RDIM_SrcFileLineMapFragment, 1);
fragment->seq = seq;
RDIM_SLLQueuePush(src_file->first_line_map_fragment, src_file->last_line_map_fragment, fragment);
src_file->total_line_count += seq->line_count;
src_files->total_line_count += seq->line_count;
}
////////////////////////////////
//~ rjf: [Building] Line Info Building
RDI_PROC RDIM_LineTable *
rdim_line_table_chunk_list_push(RDIM_Arena *arena, RDIM_LineTableChunkList *list, RDI_U64 cap)
{
RDIM_IdxedChunkListPush(arena, list, RDIM_LineTableChunkNode, RDIM_LineTable, cap, result);
return result;
}
RDI_PROC RDI_U64
rdim_idx_from_line_table(RDIM_LineTable *line_table)
{
RDIM_IdxedChunkListElementGetIdx(line_table, idx);
return idx;
}
RDI_PROC void
rdim_line_table_chunk_list_concat_in_place(RDIM_LineTableChunkList *dst, RDIM_LineTableChunkList *to_push)
{
RDIM_IdxedChunkListConcatInPlace(RDIM_LineTableChunkNode, dst, to_push,
dst->total_seq_count += to_push->total_seq_count,
dst->total_line_count += to_push->total_line_count,
dst->total_col_count += to_push->total_col_count);
}
RDI_PROC RDIM_LineSequence *
rdim_line_table_push_sequence(RDIM_Arena *arena, RDIM_LineTableChunkList *line_tables, RDIM_LineTable *line_table, RDIM_SrcFile *src_file, RDI_U64 *voffs, RDI_U32 *line_nums, RDI_U16 *col_nums, RDI_U64 line_count)
{
RDIM_LineSequenceNode *n = push_array(arena, RDIM_LineSequenceNode, 1);
n->v.src_file = src_file;
n->v.voffs = voffs;
n->v.line_nums = line_nums;
n->v.col_nums = col_nums;
n->v.line_count = line_count;
SLLQueuePush(line_table->first_seq, line_table->last_seq, n);
line_table->seq_count += 1;
line_table->line_count += line_count;
line_table->col_count += line_count*2*(col_nums != 0);
line_tables->total_seq_count += 1;
line_tables->total_line_count += line_count;
line_tables->total_col_count += line_count*2*(col_nums != 0);
return &n->v;
}
////////////////////////////////
//~ rjf: [Building] Unit List Building
RDI_PROC RDIM_Unit *
rdim_unit_chunk_list_push(RDIM_Arena *arena, RDIM_UnitChunkList *list, RDI_U64 cap)
{
RDIM_IdxedChunkListPush(arena, list, RDIM_UnitChunkNode, RDIM_Unit, cap, result);
return result;
}
RDI_PROC RDI_U64
rdim_idx_from_unit(RDIM_Unit *unit)
{
RDIM_IdxedChunkListElementGetIdx(unit, idx);
return idx;
}
RDI_PROC void
rdim_unit_chunk_list_concat_in_place(RDIM_UnitChunkList *dst, RDIM_UnitChunkList *to_push)
{
RDIM_IdxedChunkListConcatInPlace(RDIM_UnitChunkNode, dst, to_push);
}
////////////////////////////////
//~ rjf: [Building] Type Info Building
//- rjf: type nodes
RDI_PROC RDIM_Type **
rdim_array_from_type_list(RDIM_Arena *arena, RDIM_TypeList list)
{
RDIM_Type **arr = push_array(arena, RDIM_Type *, list.count);
U64 i = 0;
for(RDIM_TypeNode *n = list.first; n != 0; n = n->next, ++i)
{
arr[i] = n->v;
}
return arr;
}
RDI_PROC RDIM_TypeNode *
rdim_type_list_push(RDIM_Arena *arena, RDIM_TypeList *list, RDIM_Type *v)
{
RDIM_TypeNode *n = push_array(arena, RDIM_TypeNode, 1);
n->v = v;
SLLQueuePush(list->first, list->last, n);
list->count += 1;
return n;
}
RDI_PROC RDIM_Type *
rdim_type_chunk_list_push(RDIM_Arena *arena, RDIM_TypeChunkList *list, RDI_U64 cap)
{
RDIM_IdxedChunkListPush(arena, list, RDIM_TypeChunkNode, RDIM_Type, cap, result);
return result;
}
RDI_PROC RDI_U64
rdim_idx_from_type(RDIM_Type *type)
{
RDIM_IdxedChunkListElementGetIdx(type, idx);
return idx;
}
RDI_PROC void
rdim_type_chunk_list_concat_in_place(RDIM_TypeChunkList *dst, RDIM_TypeChunkList *to_push)
{
RDIM_IdxedChunkListConcatInPlace(RDIM_TypeChunkNode, dst, to_push);
}
//- rjf: UDTs
RDI_PROC RDIM_UDT *
rdim_udt_chunk_list_push(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDI_U64 cap)
{
RDIM_IdxedChunkListPush(arena, list, RDIM_UDTChunkNode, RDIM_UDT, cap, result);
return result;
}
RDI_PROC RDI_U64
rdim_idx_from_udt(RDIM_UDT *udt)
{
RDIM_IdxedChunkListElementGetIdx(udt, idx);
return idx;
}
RDI_PROC void
rdim_udt_chunk_list_concat_in_place(RDIM_UDTChunkList *dst, RDIM_UDTChunkList *to_push)
{
RDIM_IdxedChunkListConcatInPlace(RDIM_UDTChunkNode, dst, to_push,
dst->total_member_count += to_push->total_member_count,
dst->total_enum_val_count += to_push->total_enum_val_count);
}
RDI_PROC RDIM_UDTMember *
rdim_udt_push_member(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDIM_UDT *udt)
{
RDIM_UDTMember *mem = rdim_push_array(arena, RDIM_UDTMember, 1);
RDIM_SLLQueuePush(udt->first_member, udt->last_member, mem);
udt->member_count += 1;
list->total_member_count += 1;
return mem;
}
RDI_PROC RDIM_UDTEnumVal *
rdim_udt_push_enum_val(RDIM_Arena *arena, RDIM_UDTChunkList *list, RDIM_UDT *udt)
{
RDIM_UDTEnumVal *mem = rdim_push_array(arena, RDIM_UDTEnumVal, 1);
RDIM_SLLQueuePush(udt->first_enum_val, udt->last_enum_val, mem);
udt->enum_val_count += 1;
list->total_enum_val_count += 1;
return mem;
}
////////////////////////////////
//~ rjf: [Building] Symbol Info Building
RDI_PROC RDIM_Symbol *
rdim_symbol_chunk_list_push(RDIM_Arena *arena, RDIM_SymbolChunkList *list, RDI_U64 cap)
{
RDIM_IdxedChunkListPush(arena, list, RDIM_SymbolChunkNode, RDIM_Symbol, cap, result);
return result;
}
RDI_PROC RDI_U64
rdim_idx_from_symbol(RDIM_Symbol *symbol)
{
RDIM_IdxedChunkListElementGetIdx(symbol, idx);
return idx;
}
RDI_PROC void
rdim_symbol_chunk_list_concat_in_place(RDIM_SymbolChunkList *dst, RDIM_SymbolChunkList *to_push)
{
RDIM_IdxedChunkListConcatInPlace(RDIM_SymbolChunkNode, dst, to_push, dst->total_value_data_size += to_push->total_value_data_size);
}
internal void
rdim_symbol_push_value_data(RDIM_Arena *arena, RDIM_SymbolChunkList *list, RDIM_Symbol *symbol, RDIM_String8 data)
{
symbol->value_data = rdim_str8_copy(arena, data);
list->total_value_data_size += data.size;
}
////////////////////////////////
//~ rjf: [Building] Inline Site Info Building
RDI_PROC RDIM_InlineSite *
rdim_inline_site_chunk_list_push(RDIM_Arena *arena, RDIM_InlineSiteChunkList *list, RDI_U64 cap)
{
RDIM_IdxedChunkListPush(arena, list, RDIM_InlineSiteChunkNode, RDIM_InlineSite, cap, result);
return result;
}
RDI_PROC RDI_U64
rdim_idx_from_inline_site(RDIM_InlineSite *inline_site)
{
RDIM_IdxedChunkListElementGetIdx(inline_site, idx);
return idx;
}
RDI_PROC void
rdim_inline_site_chunk_list_concat_in_place(RDIM_InlineSiteChunkList *dst, RDIM_InlineSiteChunkList *to_push)
{
RDIM_IdxedChunkListConcatInPlace(RDIM_InlineSiteChunkNode, dst, to_push);
}
////////////////////////////////
//~ rjf: [Building] Location Info Building
//- rjf: bytecode
RDI_PROC void
rdim_bytecode_push_op(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode, RDI_EvalOp op, RDI_U64 p)
{
RDI_U16 ctrlbits = rdi_eval_op_ctrlbits_table[op];
RDI_U32 p_size = RDI_DECODEN_FROM_CTRLBITS(ctrlbits);
RDIM_EvalBytecodeOp *node = rdim_push_array(arena, RDIM_EvalBytecodeOp, 1);
node->op = op;
node->p_size = p_size;
node->p = p;
RDIM_SLLQueuePush(bytecode->first_op, bytecode->last_op, node);
bytecode->op_count += 1;
bytecode->encoded_size += 1 + p_size;
}
RDI_PROC void
rdim_bytecode_push_uconst(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode, RDI_U64 x)
{
if(x <= 0xFF)
{
rdim_bytecode_push_op(arena, bytecode, RDI_EvalOp_ConstU8, x);
}
else if(x <= 0xFFFF)
{
rdim_bytecode_push_op(arena, bytecode, RDI_EvalOp_ConstU16, x);
}
else if(x <= 0xFFFFFFFF)
{
rdim_bytecode_push_op(arena, bytecode, RDI_EvalOp_ConstU32, x);
}
else
{
rdim_bytecode_push_op(arena, bytecode, RDI_EvalOp_ConstU64, x);
}
}
RDI_PROC void
rdim_bytecode_push_sconst(RDIM_Arena *arena, RDIM_EvalBytecode *bytecode, RDI_S64 x)
{
if(-0x80 <= x && x <= 0x7F)
{
rdim_bytecode_push_op(arena, bytecode, RDI_EvalOp_ConstU8, (RDI_U64)x);
rdim_bytecode_push_op(arena, bytecode, RDI_EvalOp_TruncSigned, 8);
}
else if(-0x8000 <= x && x <= 0x7FFF)
{
rdim_bytecode_push_op(arena, bytecode, RDI_EvalOp_ConstU16, (RDI_U64)x);
rdim_bytecode_push_op(arena, bytecode, RDI_EvalOp_TruncSigned, 16);
}
else if(-0x80000000ll <= x && x <= 0x7FFFFFFFll)
{
rdim_bytecode_push_op(arena, bytecode, RDI_EvalOp_ConstU32, (RDI_U64)x);
rdim_bytecode_push_op(arena, bytecode, RDI_EvalOp_TruncSigned, 32);
}
else
{
rdim_bytecode_push_op(arena, bytecode, RDI_EvalOp_ConstU64, (RDI_U64)x);
}
}
RDI_PROC void
rdim_bytecode_concat_in_place(RDIM_EvalBytecode *left_dst, RDIM_EvalBytecode *right_destroyed)
{
if(right_destroyed->first_op != 0)
{
if(left_dst->first_op == 0)
{
rdim_memcpy_struct(left_dst, right_destroyed);
}
else
{
left_dst->last_op->next = right_destroyed->first_op;
left_dst->last_op = right_destroyed->last_op;
left_dst->op_count += right_destroyed->op_count;
left_dst->encoded_size += right_destroyed->encoded_size;
}
rdim_memzero_struct(right_destroyed);
}
}
//- rjf: locations
RDI_PROC RDI_U64
rdim_encoded_size_from_location_info(RDIM_LocationInfo *info)
{
RDI_U64 result = 0;
switch((RDI_LocationKindEnum)info->kind)
{
case RDI_LocationKind_NULL:{}break;
case RDI_LocationKind_AddrBytecodeStream:
case RDI_LocationKind_ValBytecodeStream:
{
result = sizeof(RDI_LocationBytecodeStream) + info->bytecode.encoded_size + 1;
}break;
case RDI_LocationKind_AddrRegPlusU16:
case RDI_LocationKind_AddrAddrRegPlusU16:
{
result = sizeof(RDI_LocationRegPlusU16);
}break;
case RDI_LocationKind_ValReg:
{
result = sizeof(RDI_LocationReg);
}break;
}
return result;
}
RDI_PROC RDIM_Location *
rdim_location_chunk_list_push_new(RDIM_Arena *arena, RDIM_LocationChunkList *list, RDI_U64 cap, RDIM_LocationInfo *info)
{
RDIM_IdxedChunkListPush(arena, list, RDIM_LocationChunkNode, RDIM_Location, cap, result, n->base_encoding_off = list->total_encoded_size);
{
RDI_U64 encoded_size = rdim_encoded_size_from_location_info(info);
rdim_memcpy_struct(&result->info, info);
result->relative_encoding_off = list->last->encoded_size;
list->last->encoded_size += encoded_size;
list->total_encoded_size += encoded_size;
}
return result;
}
RDI_PROC RDI_U64
rdim_off_from_location(RDIM_Location *location)
{
RDI_U64 off = 0;
if(location != 0 && location->chunk != 0)
{
off = location->chunk->base_encoding_off + location->relative_encoding_off + 1;
}
return off;
}
RDI_PROC void
rdim_location_chunk_list_concat_in_place(RDIM_LocationChunkList *dst, RDIM_LocationChunkList *to_push)
{
for(RDIM_LocationChunkNode *n = to_push->first; n != 0; n = n->next)
{
n->base_encoding_off += dst->total_encoded_size;
}
RDIM_IdxedChunkListConcatInPlace(RDIM_LocationChunkNode, dst, to_push, dst->total_encoded_size += to_push->total_encoded_size);
}
////////////////////////////////
//~ rjf: [Building] Scope Info Building
RDI_PROC RDIM_Scope *
rdim_scope_chunk_list_push(RDIM_Arena *arena, RDIM_ScopeChunkList *list, RDI_U64 cap)
{
RDIM_IdxedChunkListPush(arena, list, RDIM_ScopeChunkNode, RDIM_Scope, cap, result);
return result;
}
RDI_PROC RDI_U64
rdim_idx_from_scope(RDIM_Scope *scope)
{
RDIM_IdxedChunkListElementGetIdx(scope, idx);
return idx;
}
RDI_PROC void
rdim_scope_chunk_list_concat_in_place(RDIM_ScopeChunkList *dst, RDIM_ScopeChunkList *to_push)
{
RDIM_IdxedChunkListConcatInPlace(RDIM_ScopeChunkNode, dst, to_push,
dst->scope_voff_count += to_push->scope_voff_count,
dst->local_count += to_push->local_count,
dst->location_case_count += to_push->location_case_count);
}
RDI_PROC void
rdim_scope_push_voff_range(RDIM_Arena *arena, RDIM_ScopeChunkList *list, RDIM_Scope *scope, RDIM_Rng1U64 range)
{
rdim_rng1u64_list_push(arena, &scope->voff_ranges, range);
list->scope_voff_count += 2;
}
RDI_PROC RDIM_Local *
rdim_scope_push_local(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Scope *scope)
{
RDIM_Local *local = rdim_push_array(arena, RDIM_Local, 1);
RDIM_SLLQueuePush(scope->first_local, scope->last_local, local);
scope->local_count += 1;
scopes->local_count += 1;
return local;
}
RDI_PROC RDIM_LocationCase *
rdim_local_push_location_case(RDIM_Arena *arena, RDIM_ScopeChunkList *scopes, RDIM_Local *local, RDIM_Location *location, RDIM_Rng1U64 voff_range)
{
RDIM_LocationCase *loc_case = rdim_push_array(arena, RDIM_LocationCase, 1);
RDIM_SLLQueuePush(local->location_cases.first, local->location_cases.last, loc_case);
local->location_cases.count += 1;
loc_case->location = location;
loc_case->voff_range = voff_range;
scopes->location_case_count += 1;
return loc_case;
}
////////////////////////////////
//~ rjf: [Baking Helpers] Deduplicated String Baking Map
//- rjf: chunk lists
RDI_PROC RDIM_BakeString *
rdim_bake_string_chunk_list_push(RDIM_Arena *arena, RDIM_BakeStringChunkList *list, RDI_U64 cap)
{
RDIM_BakeStringChunkNode *n = list->last;
if(n == 0 || n->count >= n->cap)
{
n = rdim_push_array(arena, RDIM_BakeStringChunkNode, 1);
n->cap = cap;
n->v = rdim_push_array(arena, RDIM_BakeString, n->cap);
RDIM_SLLQueuePush(list->first, list->last, n);
list->chunk_count += 1;
}
RDIM_BakeString *s = &n->v[n->count];
n->count += 1;
list->total_count += 1;
return s;
}
RDI_PROC void
rdim_bake_string_chunk_list_concat_in_place(RDIM_BakeStringChunkList *dst, RDIM_BakeStringChunkList *to_push)
{
for(RDIM_BakeStringChunkNode *n = to_push->first; n != 0; n = n->next)
{
n->base_idx += dst->total_count;
}
if(dst->last != 0 && to_push->first != 0)
{
dst->last->next = to_push->first;
dst->last = to_push->last;
dst->chunk_count += to_push->chunk_count;
dst->total_count += to_push->total_count;
}
else if(dst->first == 0)
{
rdim_memcpy_struct(dst, to_push);
}
rdim_memzero_struct(to_push);
}
RDI_PROC RSFORCEINLINE int
rdim_bake_string_is_before(void *l, void *r)
{
return str8_is_before(((RDIM_BakeString *)l)->string, ((RDIM_BakeString *)r)->string);
}
RDI_PROC RDIM_BakeStringChunkList
rdim_bake_string_chunk_list_sorted_from_unsorted(RDIM_Arena *arena, RDIM_BakeStringChunkList *src)
{
//- rjf: produce unsorted destination list with single chunk node
RDIM_BakeStringChunkList dst = {0};
for(RDIM_BakeStringChunkNode *n = src->first; n != 0; n = n->next)
{
for(RDI_U64 idx = 0; idx < n->count; idx += 1)
{
RDIM_BakeString *src_str = &n->v[idx];
RDIM_BakeString *dst_str = rdim_bake_string_chunk_list_push(arena, &dst, src->total_count);
rdim_memcpy_struct(dst_str, src_str);
}
}
//- rjf: sort chunk node
if(dst.first != 0)
{
radsort(dst.first->v, dst.first->count, rdim_bake_string_is_before);
}
//- rjf: iterate sorted chunk node, remove duplicates, count # of duplicates
RDI_U64 num_duplicates = 0;
if(dst.first != 0)
{
RDI_U64 last_idx = 0;
for(RDI_U64 idx = 1; idx < dst.first->count; idx += 1)
{
if(rdim_str8_match(dst.first->v[last_idx].string, dst.first->v[idx].string, 0))
{
rdim_memzero_struct(&dst.first->v[idx]);
num_duplicates += 1;
}
else
{
last_idx = idx;
}
}
}
//- rjf: iterate sorted chunk node, make non-empty elements contiguous
if(num_duplicates != 0)
{
RDI_U64 last_idx = 0;
for(RDI_U64 idx = 1; idx < dst.first->count; idx += 1)
{
if(last_idx == 0 &&
dst.first->v[idx].string.RDIM_String8_SizeMember == 0 &&
dst.first->v[idx].hash == 0)
{
last_idx = idx;
}
if(last_idx != 0 && dst.first->v[idx].string.RDIM_String8_SizeMember != 0)
{
rdim_memcpy_struct(&dst.first->v[last_idx], &dst.first->v[idx]);
rdim_memzero_struct(&dst.first->v[idx]);
last_idx += 1;
}
}
//- rjf: pop extras
if(num_duplicates != 0)
{
RDI_U64 arena_pos_pre_pop = rdim_arena_pos(arena);
rdim_arena_pop_to(arena, arena_pos_pre_pop - num_duplicates*sizeof(dst.first->v[0]));
dst.first->count -= num_duplicates;
dst.first->cap -= num_duplicates;
dst.total_count -= num_duplicates;
}
}
return dst;
}
//- rjf: loose map
RDI_PROC RDIM_BakeStringMapLoose *
rdim_bake_string_map_loose_make(RDIM_Arena *arena, RDIM_BakeStringMapTopology *top)
{
RDIM_BakeStringMapLoose *map = rdim_push_array(arena, RDIM_BakeStringMapLoose, 1);
map->slots = rdim_push_array(arena, RDIM_BakeStringChunkList *, top->slots_count);
return map;
}
RDI_PROC void
rdim_bake_string_map_loose_insert(RDIM_Arena *arena, RDIM_BakeStringMapTopology *map_topology, RDIM_BakeStringMapLoose *map, RDI_U64 chunk_cap, RDIM_String8 string)
{
if(string.RDIM_String8_SizeMember != 0)
{
RDI_U64 hash = rdi_hash(string.RDIM_String8_BaseMember, string.RDIM_String8_SizeMember);
RDI_U64 slot_idx = hash%map_topology->slots_count;
RDIM_BakeStringChunkList *slot = map->slots[slot_idx];
if(slot == 0)
{
slot = map->slots[slot_idx] = rdim_push_array(arena, RDIM_BakeStringChunkList, 1);
}
RDI_S32 is_duplicate = 0;
for(RDIM_BakeStringChunkNode *n = slot->first; n != 0; n = n->next)
{
for(RDI_U64 idx = 0; idx < n->count; idx += 1)
{
if(rdim_str8_match(n->v[idx].string, string, 0))
{
is_duplicate = 1;
goto break_all;
}
}
}
break_all:;
if(!is_duplicate)
{
RDIM_BakeString *bstr = rdim_bake_string_chunk_list_push(arena, slot, chunk_cap);
bstr->string = string;
bstr->hash = hash;
}
}
}
RDI_PROC RDIM_BakeStringMapBaseIndices
rdim_bake_string_map_base_indices_from_map_loose(RDIM_Arena *arena, RDIM_BakeStringMapTopology *map_topology, RDIM_BakeStringMapLoose *map)
{
RDIM_BakeStringMapBaseIndices indices = {0};
indices.slots_base_idxs = rdim_push_array(arena, RDI_U64, map_topology->slots_count+1);
RDI_U64 total_count = 0;
for(RDI_U64 idx = 0; idx < map_topology->slots_count; idx += 1)
{
indices.slots_base_idxs[idx] += total_count;
if(map->slots[idx] != 0)
{
total_count += map->slots[idx]->total_count;
}
}
indices.slots_base_idxs[map_topology->slots_count] = total_count;
return indices;
}
//- rjf: finalized / tight map
RDI_PROC RDI_U32
rdim_bake_idx_from_string(RDIM_BakeStringMapTight *map, RDIM_String8 string)
{
RDI_U32 idx = 0;
if(string.RDIM_String8_SizeMember != 0)
{
RDI_U64 hash = rdi_hash(string.RDIM_String8_BaseMember, string.RDIM_String8_SizeMember);
RDI_U64 slot_idx = hash%map->slots_count;
for(RDIM_BakeStringChunkNode *n = map->slots[slot_idx].first; n != 0; n = n->next)
{
for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1)
{
if(n->v[chunk_idx].hash == hash && rdim_str8_match(n->v[chunk_idx].string, string, 0))
{
idx = map->slots_base_idxs[slot_idx] + n->base_idx + chunk_idx + 1;
break;
}
}
}
}
return idx;
}
////////////////////////////////
//~ rjf: [Baking Helpers] Deduplicated Index Run Baking Map
//- rjf: bake idx run map reading/writing
RDI_PROC RDI_U64
rdim_hash_from_idx_run(RDI_U32 *idx_run, RDI_U32 count)
{
RDI_U64 hash = 5381;
RDI_U32 *ptr = idx_run;
RDI_U32 *opl = idx_run + count;
for(;ptr < opl; ptr += 1)
{
hash = ((hash << 5) + hash) + (*ptr);
}
return hash;
}
//- rjf: chunk lists
RDI_PROC RDIM_BakeIdxRun *
rdim_bake_idx_run_chunk_list_push(RDIM_Arena *arena, RDIM_BakeIdxRunChunkList *list, RDI_U64 cap)
{
RDIM_BakeIdxRunChunkNode *n = list->last;
if(n == 0 || n->count >= n->cap)
{
n = rdim_push_array(arena, RDIM_BakeIdxRunChunkNode, 1);
n->cap = cap;
n->v = rdim_push_array(arena, RDIM_BakeIdxRun, n->cap);
RDIM_SLLQueuePush(list->first, list->last, n);
list->chunk_count += 1;
}
RDIM_BakeIdxRun *s = &n->v[n->count];
n->count += 1;
list->total_count += 1;
return s;
}
RDI_PROC void
rdim_bake_idx_run_chunk_list_concat_in_place(RDIM_BakeIdxRunChunkList *dst, RDIM_BakeIdxRunChunkList *to_push)
{
if(dst->last != 0 && to_push->first != 0)
{
dst->last->next = to_push->first;
dst->last = to_push->last;
dst->chunk_count += to_push->chunk_count;
dst->total_count += to_push->total_count;
}
else if(dst->first == 0)
{
rdim_memcpy_struct(dst, to_push);
}
rdim_memzero_struct(to_push);
}
RDI_PROC RSFORCEINLINE int
rdim_bake_idx_run_is_before(void *l, void *r)
{
B32 is_less_than = 0;
{
RDIM_BakeIdxRun *lir = (RDIM_BakeIdxRun *)l;
RDIM_BakeIdxRun *rir = (RDIM_BakeIdxRun *)r;
U64 common_count = Min(lir->count, rir->count);
for(U64 off = 0; off < common_count; off += 1)
{
if(lir->idxes[off] < rir->idxes[off])
{
is_less_than = 1;
break;
}
else if(lir->idxes[off] > rir->idxes[off])
{
is_less_than = 0;
break;
}
else if(off+1 == common_count)
{
is_less_than = (lir->count < rir->count);
}
}
}
return is_less_than;
}
RDI_PROC RDIM_BakeIdxRunChunkList
rdim_bake_idx_run_chunk_list_sorted_from_unsorted(RDIM_Arena *arena, RDIM_BakeIdxRunChunkList *src)
{
//- rjf: produce unsorted destination list with single chunk node
RDIM_BakeIdxRunChunkList dst = {0};
for(RDIM_BakeIdxRunChunkNode *n = src->first; n != 0; n = n->next)
{
for(RDI_U64 idx = 0; idx < n->count; idx += 1)
{
RDIM_BakeIdxRun *src_str = &n->v[idx];
RDIM_BakeIdxRun *dst_str = rdim_bake_idx_run_chunk_list_push(arena, &dst, src->total_count);
rdim_memcpy_struct(dst_str, src_str);
}
}
//- rjf: sort chunk node
if(dst.first != 0)
{
radsort(dst.first->v, dst.first->count, rdim_bake_idx_run_is_before);
}
//- rjf: iterate sorted chunk node, remove duplicates, count # of duplicates
RDI_U64 num_duplicates = 0;
if(dst.first != 0)
{
RDI_U64 last_idx = 0;
for(RDI_U64 idx = 1; idx < dst.first->count; idx += 1)
{
if(dst.first->v[last_idx].count == dst.first->v[idx].count &&
MemoryMatch(dst.first->v[last_idx].idxes,
dst.first->v[idx].idxes,
sizeof(dst.first->v[idx].idxes[0]) * dst.first->v[idx].count))
{
rdim_memzero_struct(&dst.first->v[idx]);
num_duplicates += 1;
}
else
{
last_idx = idx;
}
}
}
//- rjf: iterate sorted chunk node, make non-empty elements contiguous
if(num_duplicates != 0)
{
RDI_U64 last_idx = 0;
for(RDI_U64 idx = 1; idx < dst.first->count; idx += 1)
{
if(last_idx == 0 && dst.first->v[idx].hash == 0)
{
last_idx = idx;
}
if(last_idx != 0 && dst.first->v[idx].hash != 0)
{
rdim_memcpy_struct(&dst.first->v[last_idx], &dst.first->v[idx]);
rdim_memzero_struct(&dst.first->v[idx]);
last_idx += 1;
}
}
//- rjf: pop extras
if(num_duplicates != 0)
{
RDI_U64 arena_pos_pre_pop = rdim_arena_pos(arena);
rdim_arena_pop_to(arena, arena_pos_pre_pop - num_duplicates*sizeof(dst.first->v[0]));
dst.first->count -= num_duplicates;
dst.first->cap -= num_duplicates;
dst.total_count -= num_duplicates;
}
}
return dst;
}
//- rjf: loose map
RDI_PROC RDIM_BakeIdxRunMapLoose *
rdim_bake_idx_run_map_loose_make(RDIM_Arena *arena, RDIM_BakeIdxRunMapTopology *top)
{
RDIM_BakeIdxRunMapLoose *map = rdim_push_array(arena, RDIM_BakeIdxRunMapLoose, 1);
map->slots = rdim_push_array(arena, RDIM_BakeIdxRunChunkList *, top->slots_count);
map->slots_idx_counts = rdim_push_array(arena, RDI_U64, top->slots_count);
return map;
}
RDI_PROC void
rdim_bake_idx_run_map_loose_insert(RDIM_Arena *arena, RDIM_BakeIdxRunMapTopology *map_topology, RDIM_BakeIdxRunMapLoose *map, RDI_U64 chunk_cap, RDI_U32 *idxes, RDI_U32 count)
{
if(count != 0)
{
RDI_U64 hash = rdim_hash_from_idx_run(idxes, count);
RDI_U64 slot_idx = hash%map_topology->slots_count;
RDIM_BakeIdxRunChunkList *slot = map->slots[slot_idx];
if(slot == 0)
{
slot = map->slots[slot_idx] = rdim_push_array(arena, RDIM_BakeIdxRunChunkList, 1);
}
RDI_S32 is_duplicate = 0;
for(RDIM_BakeIdxRunChunkNode *n = slot->first; n != 0; n = n->next)
{
for(RDI_U64 idx = 0; idx < n->count; idx += 1)
{
if(n->v[idx].hash == hash &&
n->v[idx].count == count &&
MemoryMatch(n->v[idx].idxes, idxes, sizeof(idxes[0])*count))
{
is_duplicate = 1;
goto break_all;
}
}
}
break_all:;
if(!is_duplicate)
{
RDIM_BakeIdxRun *bir = rdim_bake_idx_run_chunk_list_push(arena, slot, chunk_cap);
bir->hash = hash;
bir->count = count;
bir->idxes = idxes;
map->slots_idx_counts[slot_idx] += count;
}
}
}
//- rjf: finalized / tight map
RDI_PROC RDI_U32
rdim_bake_idx_from_idx_run(RDIM_BakeIdxRunMap *map, RDI_U32 *idxes, RDI_U32 count)
{
RDI_U32 idx = 0;
if(count != 0)
{
RDI_U64 hash = rdim_hash_from_idx_run(idxes, count);
RDI_U64 slot_idx = hash%map->slots_count;
RDI_U64 off = 0;
for(RDIM_BakeIdxRunChunkNode *n = map->slots[slot_idx].first; n != 0; n = n->next)
{
for(RDI_U64 chunk_idx = 0; chunk_idx < n->count; chunk_idx += 1)
{
if(n->v[chunk_idx].hash == hash &&
n->v[chunk_idx].count == count &&
MemoryMatch(n->v[chunk_idx].idxes, idxes, sizeof(idxes[0])*count))
{
idx = (RDI_U32)(map->slots_base_idxs[slot_idx] + off); // TODO(rjf): @u64_to_u32
goto end_lookup;
}
off += n->v[chunk_idx].count;
}
}
end_lookup:;
}
return idx;
}
////////////////////////////////
//~ rjf: [Baking Helpers] Deduplicated Name Map Baking Map
//- rjf: chunk lists
RDI_PROC RDIM_BakeName *
rdim_bake_name_chunk_list_push(RDIM_Arena *arena, RDIM_BakeNameChunkList *list, RDI_U64 cap)
{
RDIM_BakeNameChunkNode *n = list->last;
if(n == 0 || n->count >= n->cap)
{
n = rdim_push_array(arena, RDIM_BakeNameChunkNode, 1);
n->cap = cap;
n->base_idx = list->total_count;
n->v = rdim_push_array(arena, RDIM_BakeName, n->cap);
RDIM_SLLQueuePush(list->first, list->last, n);
list->chunk_count += 1;
}
RDIM_BakeName *result = &n->v[n->count];
n->count += 1;
list->total_count += 1;
return result;
}
RDI_PROC void
rdim_bake_name_chunk_list_concat_in_place(RDIM_BakeNameChunkList *dst, RDIM_BakeNameChunkList *to_push)
{
for(RDIM_BakeNameChunkNode *n = to_push->first; n != 0; n = n->next)
{
n->base_idx += dst->total_count;
}
if(dst->last != 0 && to_push->first != 0)
{
dst->last->next = to_push->first;
dst->last = to_push->last;
dst->chunk_count += to_push->chunk_count;
dst->total_count += to_push->total_count;
}
else if(dst->first == 0)
{
rdim_memcpy_struct(dst, to_push);
}
rdim_memzero_struct(to_push);
}
RDI_PROC RSFORCEINLINE int
rdim_bake_name_is_before(void *l, void *r)
{
RDIM_BakeName *lhs = (RDIM_BakeName *)l;
RDIM_BakeName *rhs = (RDIM_BakeName *)r;
B32 lhs_name_lt = str8_is_before(lhs->string, rhs->string);
B32 is_before = lhs_name_lt;
if(!lhs_name_lt)
{
B32 rhs_name_lt = str8_is_before(rhs->string, lhs->string);
if(!rhs_name_lt)
{
is_before = (lhs->idx > rhs->idx);
}
}
return is_before;
}
RDI_PROC RDIM_BakeNameChunkList
rdim_bake_name_chunk_list_sorted_from_unsorted(RDIM_Arena *arena, RDIM_BakeNameChunkList *src)
{
//- rjf: produce unsorted destination list with single chunk node
RDIM_BakeNameChunkList dst = {0};
for(RDIM_BakeNameChunkNode *n = src->first; n != 0; n = n->next)
{
for(RDI_U64 idx = 0; idx < n->count; idx += 1)
{
RDIM_BakeName *src_str = &n->v[idx];
RDIM_BakeName *dst_str = rdim_bake_name_chunk_list_push(arena, &dst, src->total_count);
rdim_memcpy_struct(dst_str, src_str);
}
}
//- rjf: sort chunk node
if(dst.first != 0)
{
radsort(dst.first->v, dst.first->count, rdim_bake_name_is_before);
}
//- rjf: iterate sorted chunk node, remove duplicates, count # of duplicates
RDI_U64 num_duplicates = 0;
if(dst.first != 0)
{
RDI_U64 last_idx = 0;
for(RDI_U64 idx = 1; idx < dst.first->count; idx += 1)
{
if(rdim_str8_match(dst.first->v[last_idx].string, dst.first->v[idx].string, 0) &&
dst.first->v[last_idx].idx == dst.first->v[idx].idx)
{
rdim_memzero_struct(&dst.first->v[idx]);
num_duplicates += 1;
}
else
{
last_idx = idx;
}
}
}
//- rjf: iterate sorted chunk node, make non-empty elements contiguous
if(num_duplicates != 0)
{
RDI_U64 last_idx = 0;
for(RDI_U64 idx = 1; idx < dst.first->count; idx += 1)
{
if(last_idx == 0 &&
dst.first->v[idx].string.RDIM_String8_SizeMember == 0 &&
dst.first->v[idx].hash == 0)
{
last_idx = idx;
}
if(last_idx != 0 && dst.first->v[idx].string.RDIM_String8_SizeMember != 0)
{
rdim_memcpy_struct(&dst.first->v[last_idx], &dst.first->v[idx]);
rdim_memzero_struct(&dst.first->v[idx]);
last_idx += 1;
}
}
//- rjf: pop extras
if(num_duplicates != 0)
{
RDI_U64 arena_pos_pre_pop = rdim_arena_pos(arena);
rdim_arena_pop_to(arena, arena_pos_pre_pop - num_duplicates*sizeof(dst.first->v[0]));
dst.first->count -= num_duplicates;
dst.first->cap -= num_duplicates;
dst.total_count -= num_duplicates;
}
}
return dst;
}
//- rjf: bake name chunk list maps
RDI_PROC RDIM_BakeNameMap *
rdim_bake_name_map_make(RDIM_Arena *arena, RDIM_BakeNameMapTopology *top)
{
RDIM_BakeNameMap *map = rdim_push_array(arena, RDIM_BakeNameMap, 1);
map->slots = rdim_push_array(arena, RDIM_BakeNameChunkList *, top->slots_count);
return map;
}
RDI_PROC void
rdim_bake_name_map_insert(RDIM_Arena *arena, RDIM_BakeNameMapTopology *map_topology, RDIM_BakeNameMap *map, RDI_U64 chunk_cap, RDIM_String8 string, RDI_U64 idx)
{
if(string.RDIM_String8_SizeMember != 0)
{
RDI_U64 hash = rdi_hash(string.RDIM_String8_BaseMember, string.RDIM_String8_SizeMember);
RDI_U64 slot_idx = hash%map_topology->slots_count;
RDIM_BakeNameChunkList *slot = map->slots[slot_idx];
if(slot == 0)
{
slot = map->slots[slot_idx] = rdim_push_array(arena, RDIM_BakeNameChunkList, 1);
}
RDI_S32 is_duplicate = 0;
for(RDIM_BakeNameChunkNode *n = slot->first; n != 0; n = n->next)
{
for(RDI_U64 idx = 0; idx < n->count; idx += 1)
{
if(rdim_str8_match(n->v[idx].string, string, 0) &&
n->v[idx].idx == idx)
{
is_duplicate = 1;
goto break_all;
}
}
}
break_all:;
if(!is_duplicate)
{
RDIM_BakeName *bstr = rdim_bake_name_chunk_list_push(arena, slot, chunk_cap);
bstr->string = string;
bstr->idx = idx;
bstr->hash = hash;
}
}
}
////////////////////////////////
//~ rjf: [Baking Helpers] Deduplicated Path Baking Tree
RDI_PROC RDIM_BakePathNode *
rdim_bake_path_node_from_string(RDIM_BakePathTree *tree, RDIM_String8 string)
{
RDIM_BakePathNode *node = &tree->root;
RDI_U8 *ptr = string.str;
RDI_U8 *opl = string.str + string.size;
for(;ptr < opl && node != 0;)
{
// rjf: skip past slashes
for(;ptr < opl && (*ptr == '/' || *ptr == '\\'); ptr += 1);
// rjf: save beginning of non-slash range
RDI_U8 *range_first = ptr;
// rjf: skip past non-slashes
for(;ptr < opl && !(*ptr == '/' || *ptr == '\\'); ptr += 1);
// rjf: empty range -> continue
if(range_first >= ptr)
{
continue;
}
// rjf: range -> sub-directory string
RDIM_String8 sub_dir = rdim_str8(range_first, (RDI_U64)(ptr-range_first));
// rjf: sub-directory string -> find child of node
RDIM_BakePathNode *sub_dir_node = 0;
for(RDIM_BakePathNode *child = node->first_child; child != 0; child = child->next_sibling)
{
if(rdim_str8_match(child->name, sub_dir, 0))
{
sub_dir_node = child;
}
}
// rjf: .. -> go up
if(sub_dir.RDIM_String8_SizeMember == 2 &&
sub_dir.RDIM_String8_BaseMember[0] == '.' &&
sub_dir.RDIM_String8_BaseMember[1] == '.')
{
sub_dir_node = node->parent;
if(sub_dir_node == 0)
{
sub_dir_node = &tree->root;
}
}
// rjf: . -> stay here
else if(sub_dir.RDIM_String8_SizeMember == 1 &&
sub_dir.RDIM_String8_BaseMember[0] == '.')
{
sub_dir_node = node;
}
// rjf: descend to child
node = sub_dir_node;
}
return node;
}
RDI_PROC RDI_U32
rdim_bake_path_node_idx_from_string(RDIM_BakePathTree *tree, RDIM_String8 string)
{
RDIM_BakePathNode *path_node = rdim_bake_path_node_from_string(tree, string);
RDI_U32 result = 0;
if(path_node != 0)
{
result = path_node->idx;
}
return result;
}
RDI_PROC RDIM_BakePathNode *
rdim_bake_path_tree_insert(RDIM_Arena *arena, RDIM_BakePathTree *tree, RDIM_String8 string)
{
RDIM_BakePathNode *node = &tree->root;
RDI_U8 *ptr = string.str;
RDI_U8 *opl = string.str + string.size;
for(;ptr < opl;)
{
// rjf: skip past slashes
for(;ptr < opl && (*ptr == '/' || *ptr == '\\'); ptr += 1);
// rjf: save beginning of non-slash range
RDI_U8 *range_first = ptr;
// rjf: skip past non-slashes
for(;ptr < opl && !(*ptr == '/' || *ptr == '\\'); ptr += 1);
// rjf: empty range -> continue
if(range_first >= ptr)
{
continue;
}
// rjf: range -> sub-directory string
RDIM_String8 sub_dir = rdim_str8(range_first, (RDI_U64)(ptr-range_first));
// rjf: sub-directory string -> find child of node
RDIM_BakePathNode *sub_dir_node = 0;
for(RDIM_BakePathNode *child = node->first_child; child != 0; child = child->next_sibling)
{
if(rdim_str8_match(child->name, sub_dir, 0))
{
sub_dir_node = child;
}
}
// rjf: .. -> go up
if(sub_dir.RDIM_String8_SizeMember == 2 &&
sub_dir.RDIM_String8_BaseMember[0] == '.' &&
sub_dir.RDIM_String8_BaseMember[1] == '.')
{
sub_dir_node = node->parent;
if(sub_dir_node == 0)
{
sub_dir_node = &tree->root;
}
}
// rjf: . -> stay here
else if(sub_dir.RDIM_String8_SizeMember == 1 &&
sub_dir.RDIM_String8_BaseMember[0] == '.')
{
sub_dir_node = node;
}
// rjf: no child -> make one
else if(sub_dir_node == 0)
{
sub_dir_node = rdim_push_array(arena, RDIM_BakePathNode, 1);
RDIM_SLLQueuePush_N(tree->first, tree->last, sub_dir_node, next_order);
sub_dir_node->parent = node;
RDIM_SLLQueuePush_N(node->first_child, node->last_child, sub_dir_node, next_sibling);
sub_dir_node->name = rdim_str8_copy(arena, sub_dir);
sub_dir_node->idx = tree->count;
tree->count += 1;
}
// rjf: descend to child
node = sub_dir_node;
}
return node;
}
////////////////////////////////
//~ rjf: [Baking Helpers] Data Section List Building Helpers
RDI_PROC RDIM_BakeSection *
rdim_bake_section_list_push(RDIM_Arena *arena, RDIM_BakeSectionList *list)
{
RDIM_BakeSectionNode *n = rdim_push_array(arena, RDIM_BakeSectionNode, 1);
RDIM_SLLQueuePush(list->first, list->last, n);
list->count += 1;
RDIM_BakeSection *result = &n->v;
return result;
}
RDI_PROC RDIM_BakeSection *
rdim_bake_section_list_push_new_unpacked(RDIM_Arena *arena, RDIM_BakeSectionList *list, void *data, RDI_U64 size, RDI_SectionKind tag, RDI_U64 tag_idx)
{
RDIM_BakeSection *section = rdim_bake_section_list_push(arena, list);
section->data = data;
section->encoding = RDI_SectionEncoding_Unpacked;
section->encoded_size = size;
section->unpacked_size = size;
section->tag = tag;
section->tag_idx = tag_idx;
return section;
}
RDI_PROC void
rdim_bake_section_list_concat_in_place(RDIM_BakeSectionList *dst, RDIM_BakeSectionList *to_push)
{
if(dst->last != 0 && to_push->first != 0)
{
dst->last->next = to_push->first;
dst->last = to_push->last;
dst->count += to_push->count;
}
else if(to_push->first != 0)
{
rdim_memcpy_struct(dst, to_push);
}
rdim_memzero_struct(to_push);
}
////////////////////////////////
//~ rjf: [Serializing] Bake Results -> String Blobs
RDI_PROC RDIM_SerializedSection
rdim_serialized_section_make_unpacked(void *data, RDI_U64 size)
{
RDIM_SerializedSection s;
rdim_memzero_struct(&s);
s.data = data;
s.encoded_size = s.unpacked_size = size;
s.encoding = RDI_SectionEncoding_Unpacked;
return s;
}
RDI_PROC RDIM_SerializedSectionBundle
rdim_serialized_section_bundle_from_bake_results(RDIM_BakeResults *results)
{
RDIM_SerializedSectionBundle bundle;
rdim_memzero_struct(&bundle);
bundle.sections[RDI_SectionKind_TopLevelInfo] = rdim_serialized_section_make_unpacked_struct(&results->top_level_info.top_level_info);
bundle.sections[RDI_SectionKind_StringData] = rdim_serialized_section_make_unpacked_array(results->strings.string_data, results->strings.string_data_size);
bundle.sections[RDI_SectionKind_StringTable] = rdim_serialized_section_make_unpacked_array(results->strings.string_offs, results->strings.string_offs_count);
bundle.sections[RDI_SectionKind_IndexRuns] = rdim_serialized_section_make_unpacked_array(results->idx_runs.idx_runs, results->idx_runs.idx_count);
bundle.sections[RDI_SectionKind_BinarySections] = rdim_serialized_section_make_unpacked_array(results->binary_sections.binary_sections, results->binary_sections.binary_sections_count);
bundle.sections[RDI_SectionKind_FilePathNodes] = rdim_serialized_section_make_unpacked_array(results->file_paths.nodes, results->file_paths.nodes_count);
bundle.sections[RDI_SectionKind_SourceFiles] = rdim_serialized_section_make_unpacked_array(results->src_files.source_files, results->src_files.source_files_count);
bundle.sections[RDI_SectionKind_LineTables] = rdim_serialized_section_make_unpacked_array(results->line_tables.line_tables, results->line_tables.line_tables_count);
bundle.sections[RDI_SectionKind_LineInfoVOffs] = rdim_serialized_section_make_unpacked_array(results->line_tables.line_table_voffs, results->line_tables.line_table_voffs_count);
bundle.sections[RDI_SectionKind_LineInfoLines] = rdim_serialized_section_make_unpacked_array(results->line_tables.line_table_lines, results->line_tables.line_table_lines_count);
bundle.sections[RDI_SectionKind_LineInfoColumns] = rdim_serialized_section_make_unpacked_array(results->line_tables.line_table_columns, results->line_tables.line_table_columns_count);
bundle.sections[RDI_SectionKind_SourceLineMaps] = rdim_serialized_section_make_unpacked_array(results->src_files.source_line_maps, results->src_files.source_line_maps_count);
bundle.sections[RDI_SectionKind_SourceLineMapNumbers] = rdim_serialized_section_make_unpacked_array(results->src_files.source_line_map_nums, results->src_files.source_line_map_nums_count);
bundle.sections[RDI_SectionKind_SourceLineMapRanges] = rdim_serialized_section_make_unpacked_array(results->src_files.source_line_map_rngs, results->src_files.source_line_map_rngs_count);
bundle.sections[RDI_SectionKind_SourceLineMapVOffs] = rdim_serialized_section_make_unpacked_array(results->src_files.source_line_map_voffs, results->src_files.source_line_map_voffs_count);
bundle.sections[RDI_SectionKind_Units] = rdim_serialized_section_make_unpacked_array(results->units.units, results->units.units_count);
bundle.sections[RDI_SectionKind_UnitVMap] = rdim_serialized_section_make_unpacked_array(results->unit_vmap.vmap.vmap, results->unit_vmap.vmap.count);
bundle.sections[RDI_SectionKind_TypeNodes] = rdim_serialized_section_make_unpacked_array(results->type_nodes.type_nodes, results->type_nodes.type_nodes_count);
bundle.sections[RDI_SectionKind_UDTs] = rdim_serialized_section_make_unpacked_array(results->udts.udts, results->udts.udts_count);
bundle.sections[RDI_SectionKind_Members] = rdim_serialized_section_make_unpacked_array(results->udts.members, results->udts.members_count);
bundle.sections[RDI_SectionKind_EnumMembers] = rdim_serialized_section_make_unpacked_array(results->udts.enum_members, results->udts.enum_members_count);
bundle.sections[RDI_SectionKind_GlobalVariables] = rdim_serialized_section_make_unpacked_array(results->global_variables.global_variables, results->global_variables.global_variables_count);
bundle.sections[RDI_SectionKind_GlobalVMap] = rdim_serialized_section_make_unpacked_array(results->global_vmap.vmap.vmap, results->global_vmap.vmap.count);
bundle.sections[RDI_SectionKind_ThreadVariables] = rdim_serialized_section_make_unpacked_array(results->thread_variables.thread_variables, results->thread_variables.thread_variables_count);
bundle.sections[RDI_SectionKind_Constants] = rdim_serialized_section_make_unpacked_array(results->constants.constants, results->constants.constants_count);
bundle.sections[RDI_SectionKind_Procedures] = rdim_serialized_section_make_unpacked_array(results->procedures.procedures, results->procedures.procedures_count);
bundle.sections[RDI_SectionKind_Scopes] = rdim_serialized_section_make_unpacked_array(results->scopes.scopes, results->scopes.scopes_count);
bundle.sections[RDI_SectionKind_ScopeVOffData] = rdim_serialized_section_make_unpacked_array(results->scopes.scope_voffs, results->scopes.scope_voffs_count);
bundle.sections[RDI_SectionKind_ScopeVMap] = rdim_serialized_section_make_unpacked_array(results->scope_vmap.vmap.vmap, results->scope_vmap.vmap.count);
bundle.sections[RDI_SectionKind_InlineSites] = rdim_serialized_section_make_unpacked_array(results->inline_sites.inline_sites, results->inline_sites.inline_sites_count);
bundle.sections[RDI_SectionKind_Locals] = rdim_serialized_section_make_unpacked_array(results->scopes.locals, results->scopes.locals_count);
bundle.sections[RDI_SectionKind_LocationBlocks] = rdim_serialized_section_make_unpacked_array(results->location_blocks.str, results->location_blocks.size);
bundle.sections[RDI_SectionKind_LocationData] = rdim_serialized_section_make_unpacked_array(results->location_data.str, results->location_data.size);
if(results->location_blocks.size == 0)
{
bundle.sections[RDI_SectionKind_LocationBlocks] = rdim_serialized_section_make_unpacked_array(results->location_blocks2.location_blocks, results->location_blocks2.location_blocks_count);
bundle.sections[RDI_SectionKind_LocationData] = rdim_serialized_section_make_unpacked_array(results->locations.location_data, results->locations.location_data_size);
}
bundle.sections[RDI_SectionKind_ConstantValueData] = rdim_serialized_section_make_unpacked_array(results->constants.constant_value_data, results->constants.constant_value_data_size);
bundle.sections[RDI_SectionKind_ConstantValueTable] = rdim_serialized_section_make_unpacked_array(results->constants.constant_values, results->constants.constant_values_count);
bundle.sections[RDI_SectionKind_NameMaps] = rdim_serialized_section_make_unpacked_array(results->top_level_name_maps.name_maps, results->top_level_name_maps.name_maps_count);
bundle.sections[RDI_SectionKind_NameMapBuckets] = rdim_serialized_section_make_unpacked_array(results->name_maps.buckets, results->name_maps.buckets_count);
bundle.sections[RDI_SectionKind_NameMapNodes] = rdim_serialized_section_make_unpacked_array(results->name_maps.nodes, results->name_maps.nodes_count);
return bundle;
}
RDI_PROC RDIM_String8List
rdim_file_blobs_from_section_bundle(RDIM_Arena *arena, RDIM_SerializedSectionBundle *bundle)
{
RDIM_String8List strings;
rdim_memzero_struct(&strings);
{
RDIM_Temp scratch = rdim_scratch_begin(&arena, 1);
// rjf: push empty header & data section table
RDI_Header *rdi_header = rdim_push_array(arena, RDI_Header, 1);
RDI_Section *rdi_sections = rdim_push_array(arena, RDI_Section, RDI_SectionKind_COUNT);
rdim_str8_list_push(arena, &strings, rdim_str8_struct(rdi_header));
rdim_str8_list_push_align(arena, &strings, 8);
U32 data_section_off = (U32)strings.total_size;
rdim_str8_list_push(arena, &strings, rdim_str8((RDI_U8 *)rdi_sections, sizeof(RDI_Section)*RDI_SectionKind_COUNT));
// rjf: fill baked header
{
rdi_header->magic = RDI_MAGIC_CONSTANT;
rdi_header->encoding_version = RDI_ENCODING_VERSION;
rdi_header->data_section_off = data_section_off;
rdi_header->data_section_count = RDI_SectionKind_COUNT;
}
// rjf: fill baked data section table
for(RDI_SectionKind k = RDI_SectionKind_NULL; k < RDI_SectionKind_COUNT; k += 1)
{
RDI_Section *dst = rdi_sections+k;
U64 data_section_off = 0;
if(bundle->sections[k].encoded_size != 0)
{
rdim_str8_list_push_align(arena, &strings, 8);
data_section_off = strings.total_size;
rdim_str8_list_push(arena, &strings, rdim_str8((RDI_U8 *)bundle->sections[k].data, bundle->sections[k].encoded_size));
}
dst->encoding = bundle->sections[k].encoding;
dst->off = data_section_off;
dst->encoded_size = bundle->sections[k].encoded_size;
dst->unpacked_size = bundle->sections[k].unpacked_size;
}
rdim_scratch_end(scratch);
}
return strings;
}