mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-04 21:08:40 +00:00
eliminate all old evaluation bundled helpers, eliminate old fragmented eval caches; move all to unified evaluation cache
This commit is contained in:
+624
-6
@@ -7,7 +7,7 @@
|
||||
#include "eval/generated/eval.meta.c"
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Helper Functions
|
||||
//~ rjf: Basic Helpers
|
||||
|
||||
#if !defined(XXH_IMPLEMENTATION)
|
||||
# define XXH_IMPLEMENTATION
|
||||
@@ -22,7 +22,72 @@ e_hash_from_string(U64 seed, String8 string)
|
||||
return result;
|
||||
}
|
||||
|
||||
//- rjf: type key data structures
|
||||
////////////////////////////////
|
||||
//~ rjf: Expr Kind Enum Functions
|
||||
|
||||
internal RDI_EvalOp
|
||||
e_opcode_from_expr_kind(E_ExprKind kind)
|
||||
{
|
||||
RDI_EvalOp result = RDI_EvalOp_Stop;
|
||||
switch(kind)
|
||||
{
|
||||
case E_ExprKind_Neg: result = RDI_EvalOp_Neg; break;
|
||||
case E_ExprKind_LogNot: result = RDI_EvalOp_LogNot; break;
|
||||
case E_ExprKind_BitNot: result = RDI_EvalOp_BitNot; break;
|
||||
case E_ExprKind_Mul: result = RDI_EvalOp_Mul; break;
|
||||
case E_ExprKind_Div: result = RDI_EvalOp_Div; break;
|
||||
case E_ExprKind_Mod: result = RDI_EvalOp_Mod; break;
|
||||
case E_ExprKind_Add: result = RDI_EvalOp_Add; break;
|
||||
case E_ExprKind_Sub: result = RDI_EvalOp_Sub; break;
|
||||
case E_ExprKind_LShift: result = RDI_EvalOp_LShift; break;
|
||||
case E_ExprKind_RShift: result = RDI_EvalOp_RShift; break;
|
||||
case E_ExprKind_Less: result = RDI_EvalOp_Less; break;
|
||||
case E_ExprKind_LsEq: result = RDI_EvalOp_LsEq; break;
|
||||
case E_ExprKind_Grtr: result = RDI_EvalOp_Grtr; break;
|
||||
case E_ExprKind_GrEq: result = RDI_EvalOp_GrEq; break;
|
||||
case E_ExprKind_EqEq: result = RDI_EvalOp_EqEq; break;
|
||||
case E_ExprKind_NtEq: result = RDI_EvalOp_NtEq; break;
|
||||
case E_ExprKind_BitAnd: result = RDI_EvalOp_BitAnd; break;
|
||||
case E_ExprKind_BitXor: result = RDI_EvalOp_BitXor; break;
|
||||
case E_ExprKind_BitOr: result = RDI_EvalOp_BitOr; break;
|
||||
case E_ExprKind_LogAnd: result = RDI_EvalOp_LogAnd; break;
|
||||
case E_ExprKind_LogOr: result = RDI_EvalOp_LogOr; break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal B32
|
||||
e_expr_kind_is_comparison(E_ExprKind kind)
|
||||
{
|
||||
B32 result = 0;
|
||||
switch(kind)
|
||||
{
|
||||
default:{}break;
|
||||
case E_ExprKind_EqEq:
|
||||
case E_ExprKind_NtEq:
|
||||
case E_ExprKind_Less:
|
||||
case E_ExprKind_Grtr:
|
||||
case E_ExprKind_LsEq:
|
||||
case E_ExprKind_GrEq:
|
||||
{
|
||||
result = 1;
|
||||
}break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Key Type Functions
|
||||
|
||||
internal B32
|
||||
e_key_match(E_Key a, E_Key b)
|
||||
{
|
||||
B32 result = (a.u64 == b.u64);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Type Key Type Functions
|
||||
|
||||
internal void
|
||||
e_type_key_list_push(Arena *arena, E_TypeKeyList *list, E_TypeKey key)
|
||||
@@ -107,7 +172,7 @@ e_space_make(E_SpaceKind kind)
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Basic Map Functions
|
||||
//~ rjf: Map Functions
|
||||
|
||||
//- rjf: string -> num
|
||||
|
||||
@@ -277,7 +342,7 @@ e_string2expr_map_dec_poison(E_String2ExprMap *map, String8 string)
|
||||
}
|
||||
|
||||
internal E_Expr *
|
||||
e_string2expr_lookup(E_String2ExprMap *map, String8 string)
|
||||
e_string2expr_map_lookup(E_String2ExprMap *map, String8 string)
|
||||
{
|
||||
E_Expr *expr = &e_expr_nil;
|
||||
if(map->slots_count != 0)
|
||||
@@ -340,6 +405,43 @@ e_string2typekey_map_lookup(E_String2TypeKeyMap *map, String8 string)
|
||||
return key;
|
||||
}
|
||||
|
||||
//- rjf: auto hooks
|
||||
|
||||
internal E_AutoHookMap
|
||||
e_auto_hook_map_make(Arena *arena, U64 slots_count)
|
||||
{
|
||||
E_AutoHookMap map = {0};
|
||||
map.slots_count = slots_count;
|
||||
map.slots = push_array(arena, E_AutoHookSlot, map.slots_count);
|
||||
return map;
|
||||
}
|
||||
|
||||
internal void
|
||||
e_auto_hook_map_insert_new_(Arena *arena, E_AutoHookMap *map, E_AutoHookParams *params)
|
||||
{
|
||||
E_TypeKey type_key = params->type_key;
|
||||
if(params->type_pattern.size != 0)
|
||||
{
|
||||
E_Parse parse = e_push_parse_from_string(arena, params->type_pattern);
|
||||
type_key = e_type_key_from_expr(parse.expr);
|
||||
}
|
||||
E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1);
|
||||
node->type_string = str8_skip_chop_whitespace(e_type_string_from_key(arena, type_key));
|
||||
U8 pattern_split = '?';
|
||||
node->type_pattern_parts = str8_split(arena, params->type_pattern, &pattern_split, 1, StringSplitFlag_KeepEmpties);
|
||||
node->expr = e_parse_from_string(params->tag_expr_string).expr;
|
||||
if(!e_type_key_match(e_type_key_zero(), type_key))
|
||||
{
|
||||
U64 hash = e_hash_from_string(5381, node->type_string);
|
||||
U64 slot_idx = hash%map->slots_count;
|
||||
SLLQueuePush_N(map->slots[slot_idx].first, map->slots[slot_idx].last, node, hash_next);
|
||||
}
|
||||
else
|
||||
{
|
||||
SLLQueuePush_N(map->first_pattern, map->last_pattern, node, pattern_order_next);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Debug-Info-Driven Map Building Functions
|
||||
|
||||
@@ -464,13 +566,529 @@ e_push_member_map_from_rdi_voff(Arena *arena, RDI_Parsed *rdi, U64 voff)
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Base Evaluation Context Selection
|
||||
//~ rjf: Cache Creation & Selection
|
||||
|
||||
internal E_Cache *
|
||||
e_cache_alloc(void)
|
||||
{
|
||||
Arena *arena = arena_alloc();
|
||||
E_Cache *cache = push_array(arena, E_Cache, 1);
|
||||
cache->arena = arena;
|
||||
cache->arena_eval_start_pos = arena_pos(arena);
|
||||
return cache;
|
||||
}
|
||||
|
||||
internal void
|
||||
e_cache_release(E_Cache *cache)
|
||||
{
|
||||
arena_release(cache->arena);
|
||||
}
|
||||
|
||||
internal void
|
||||
e_select_cache(E_Cache *cache)
|
||||
{
|
||||
e_cache = cache;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Evaluation Phase Markers
|
||||
|
||||
internal void
|
||||
e_select_base_ctx(E_BaseCtx *ctx)
|
||||
{
|
||||
//- rjf: select base context
|
||||
if(ctx->modules == 0) { ctx->modules = &e_module_nil; }
|
||||
if(ctx->primary_module == 0) { ctx->primary_module = &e_module_nil; }
|
||||
e_base_ctx = ctx;
|
||||
e_base_ctx_gen += 1;
|
||||
|
||||
//- rjf: reset the evaluation cache
|
||||
arena_pop_to(e_cache->arena, e_cache->arena_eval_start_pos);
|
||||
e_cache->key_id_gen = 0;
|
||||
e_cache->key_slots_count = 4096;
|
||||
e_cache->key_slots = push_array(e_cache->arena, E_CacheSlot, e_cache->key_slots_count);
|
||||
e_cache->string_slots_count = 4096;
|
||||
e_cache->string_slots = push_array(e_cache->arena, E_CacheSlot, e_cache->string_slots_count);
|
||||
e_cache->free_parent_node = 0;
|
||||
e_cache->top_parent_node = 0;
|
||||
e_cache->cons_id_gen = 0;
|
||||
e_cache->cons_content_slots_count = 256;
|
||||
e_cache->cons_key_slots_count = 256;
|
||||
e_cache->cons_content_slots = push_array(e_cache->arena, E_ConsTypeSlot, e_cache->cons_content_slots_count);
|
||||
e_cache->cons_key_slots = push_array(e_cache->arena, E_ConsTypeSlot, e_cache->cons_key_slots_count);
|
||||
e_cache->member_cache_slots_count = 256;
|
||||
e_cache->member_cache_slots = push_array(e_cache->arena, E_MemberCacheSlot, e_cache->member_cache_slots_count);
|
||||
e_cache->type_cache_slots_count = 1024;
|
||||
e_cache->type_cache_slots = push_array(e_cache->arena, E_TypeCacheSlot, e_cache->type_cache_slots_count);
|
||||
e_cache->file_type_key = e_type_key_cons(.kind = E_TypeKind_Set,
|
||||
.name = str8_lit("file"),
|
||||
.irext = E_TYPE_IREXT_FUNCTION_NAME(file),
|
||||
.access = E_TYPE_ACCESS_FUNCTION_NAME(file),
|
||||
.expand =
|
||||
{
|
||||
.info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(file),
|
||||
.range= E_TYPE_EXPAND_RANGE_FUNCTION_NAME(file),
|
||||
});
|
||||
e_cache->folder_type_key = e_type_key_cons(.kind = E_TypeKind_Set,
|
||||
.name = str8_lit("folder"),
|
||||
.expand =
|
||||
{
|
||||
.info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(folder),
|
||||
.range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(folder),
|
||||
.id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(folder),
|
||||
.num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(folder),
|
||||
});
|
||||
e_cache->thread_ip_procedure = rdi_procedure_from_voff(e_base_ctx->primary_module->rdi, e_base_ctx->thread_ip_voff);
|
||||
e_cache->used_expr_map = push_array(e_cache->arena, E_UsedExprMap, 1);
|
||||
e_cache->used_expr_map->slots_count = 64;
|
||||
e_cache->used_expr_map->slots = push_array(e_cache->arena, E_UsedExprSlot, e_cache->used_expr_map->slots_count);
|
||||
e_cache->type_auto_hook_cache_map = push_array(e_cache->arena, E_TypeAutoHookCacheMap, 1);
|
||||
e_cache->type_auto_hook_cache_map->slots_count = 256;
|
||||
e_cache->type_auto_hook_cache_map->slots = push_array(e_cache->arena, E_TypeAutoHookCacheSlot, e_cache->type_auto_hook_cache_map->slots_count);
|
||||
e_cache->string_id_gen = 0;
|
||||
e_cache->string_id_map = push_array(e_cache->arena, E_StringIDMap, 1);
|
||||
e_cache->string_id_map->id_slots_count = 1024;
|
||||
e_cache->string_id_map->id_slots = push_array(e_cache->arena, E_StringIDSlot, e_cache->string_id_map->id_slots_count);
|
||||
e_cache->string_id_map->hash_slots_count = 1024;
|
||||
e_cache->string_id_map->hash_slots = push_array(e_cache->arena, E_StringIDSlot, e_cache->string_id_map->hash_slots_count);
|
||||
}
|
||||
|
||||
internal void
|
||||
e_select_ir_ctx(E_IRCtx *ctx)
|
||||
{
|
||||
if(ctx->regs_map == 0) { ctx->regs_map = &e_string2num_map_nil; }
|
||||
if(ctx->reg_alias_map == 0) { ctx->reg_alias_map = &e_string2num_map_nil; }
|
||||
if(ctx->locals_map == 0) { ctx->locals_map = &e_string2num_map_nil; }
|
||||
if(ctx->member_map == 0) { ctx->member_map = &e_string2num_map_nil; }
|
||||
if(ctx->macro_map == 0) { ctx->macro_map = push_array(e_cache->arena, E_String2ExprMap, 1); ctx->macro_map[0] = e_string2expr_map_make(e_cache->arena, 512); }
|
||||
e_ir_ctx = ctx;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Cache Accessing Functions
|
||||
|
||||
//- rjf: parent key stack
|
||||
|
||||
internal E_Key
|
||||
e_parent_key_push(E_Key key)
|
||||
{
|
||||
E_Key top = {0};
|
||||
if(e_cache->top_parent_node != 0)
|
||||
{
|
||||
top = e_cache->top_parent_node->key;
|
||||
}
|
||||
E_CacheParentNode *n = e_cache->free_parent_node;
|
||||
if(n != 0)
|
||||
{
|
||||
SLLStackPop(e_cache->free_parent_node);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = push_array(e_cache->arena, E_CacheParentNode, 1);
|
||||
}
|
||||
SLLStackPush(e_cache->top_parent_node, n);
|
||||
n->key = key;
|
||||
return top;
|
||||
}
|
||||
|
||||
internal E_Key
|
||||
e_parent_key_pop(void)
|
||||
{
|
||||
E_CacheParentNode *n = e_cache->top_parent_node;
|
||||
SLLStackPop(e_cache->top_parent_node);
|
||||
SLLStackPush(e_cache->free_parent_node, n);
|
||||
E_Key popped = n->key;
|
||||
return popped;
|
||||
}
|
||||
|
||||
//- rjf: key construction
|
||||
|
||||
internal E_Key
|
||||
e_key_from_string(String8 string)
|
||||
{
|
||||
E_Key parent_key = {0};
|
||||
if(e_cache->top_parent_node)
|
||||
{
|
||||
parent_key = e_cache->top_parent_node->key;
|
||||
}
|
||||
U64 hash = e_hash_from_string(parent_key.u64, string);
|
||||
U64 slot_idx = hash%e_cache->string_slots_count;
|
||||
E_CacheSlot *slot = &e_cache->string_slots[slot_idx];
|
||||
E_CacheNode *node = 0;
|
||||
for(E_CacheNode *n = slot->first; n != 0; n = n->string_next)
|
||||
{
|
||||
if(e_key_match(parent_key, n->bundle.parent_key) && str8_match(n->bundle.string, string, 0))
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(node == 0)
|
||||
{
|
||||
e_cache->key_id_gen += 1;
|
||||
E_Key key = {e_cache->key_id_gen};
|
||||
U64 key_hash = e_hash_from_string(5381, str8_struct(&key));
|
||||
U64 key_slot_idx = key_hash%e_cache->key_slots_count;
|
||||
E_CacheSlot *key_slot = &e_cache->key_slots[key_slot_idx];
|
||||
node = push_array(e_cache->arena, E_CacheNode, 1);
|
||||
SLLQueuePush_N(slot->first, slot->last, node, string_next);
|
||||
SLLQueuePush_N(key_slot->first, key_slot->last, node, key_next);
|
||||
node->bundle.key = key;
|
||||
node->bundle.parent_key = parent_key;
|
||||
node->bundle.string = push_str8_copy(e_cache->arena, string);
|
||||
}
|
||||
return node->bundle.key;
|
||||
}
|
||||
|
||||
internal E_Key
|
||||
e_key_from_stringf(char *fmt, ...)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String8 string = push_str8fv(scratch.arena, fmt, args);
|
||||
E_Key result = e_key_from_string(string);
|
||||
va_end(args);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal E_Key
|
||||
e_key_from_expr(E_Expr *expr)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
String8 string = e_string_from_expr(scratch.arena, expr, str8_zero());
|
||||
E_Key key = e_key_from_string(string);
|
||||
scratch_end(scratch);
|
||||
return key;
|
||||
}
|
||||
|
||||
//- rjf: base key -> node helper
|
||||
|
||||
internal E_CacheBundle *
|
||||
e_cache_bundle_from_key(E_Key key)
|
||||
{
|
||||
U64 hash = e_hash_from_string(5381, str8_struct(&key));
|
||||
U64 slot_idx = hash%e_cache->key_slots_count;
|
||||
E_CacheSlot *slot = &e_cache->key_slots[slot_idx];
|
||||
E_CacheNode *node = 0;
|
||||
for(E_CacheNode *n = slot->first; n != 0; n = n->key_next)
|
||||
{
|
||||
if(e_key_match(n->bundle.key, key))
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
E_CacheBundle *bundle = &e_cache_bundle_nil;
|
||||
if(node != 0)
|
||||
{
|
||||
bundle = &node->bundle;
|
||||
}
|
||||
return bundle;
|
||||
}
|
||||
|
||||
//- rjf: bundle -> pipeline stage outputs
|
||||
|
||||
internal E_Parse
|
||||
e_parse_from_bundle(E_CacheBundle *bundle)
|
||||
{
|
||||
if(bundle != &e_cache_bundle_nil && !(bundle->flags & E_CacheBundleFlag_Parse))
|
||||
{
|
||||
bundle->flags |= E_CacheBundleFlag_Parse;
|
||||
bundle->parse = e_push_parse_from_string(e_cache->arena, bundle->string);
|
||||
}
|
||||
E_Parse parse = bundle->parse;
|
||||
return parse;
|
||||
}
|
||||
|
||||
internal E_IRTreeAndType
|
||||
e_irtree_from_bundle(E_CacheBundle *bundle)
|
||||
{
|
||||
if(bundle != &e_cache_bundle_nil && !(bundle->flags & E_CacheBundleFlag_IRTree))
|
||||
{
|
||||
bundle->flags |= E_CacheBundleFlag_IRTree;
|
||||
E_IRTreeAndType overridden = e_irtree_from_key(bundle->parent_key);
|
||||
E_Parse parse = e_parse_from_bundle(bundle);
|
||||
bundle->irtree = e_push_irtree_and_type_from_expr(e_cache->arena, &overridden, 0, 0, parse.expr);
|
||||
}
|
||||
E_IRTreeAndType result = bundle->irtree;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
e_bytecode_from_bundle(E_CacheBundle *bundle)
|
||||
{
|
||||
if(bundle != &e_cache_bundle_nil && !(bundle->flags & E_CacheBundleFlag_Bytecode))
|
||||
{
|
||||
bundle->flags |= E_CacheBundleFlag_Bytecode;
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
E_IRTreeAndType irtree = e_irtree_from_bundle(bundle);
|
||||
E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree.root);
|
||||
bundle->bytecode = e_bytecode_from_oplist(e_cache->arena, &oplist);
|
||||
scratch_end(scratch);
|
||||
}
|
||||
String8 result = bundle->bytecode;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal E_Interpretation
|
||||
e_interpretation_from_bundle(E_CacheBundle *bundle)
|
||||
{
|
||||
if(bundle != &e_cache_bundle_nil && !(bundle->flags & E_CacheBundleFlag_Interpret))
|
||||
{
|
||||
bundle->flags |= E_CacheBundleFlag_Interpret;
|
||||
String8 bytecode = e_bytecode_from_bundle(bundle);
|
||||
E_Interpretation interpret = e_interpret(bytecode);
|
||||
bundle->interpretation = interpret;
|
||||
}
|
||||
E_Interpretation interpret = bundle->interpretation;
|
||||
return interpret;
|
||||
}
|
||||
|
||||
//- rjf: comprehensive bundle
|
||||
|
||||
internal E_Eval
|
||||
e_eval_from_bundle(E_CacheBundle *bundle)
|
||||
{
|
||||
E_Eval eval =
|
||||
{
|
||||
.key = bundle->key,
|
||||
.expr = e_parse_from_bundle(bundle).expr,
|
||||
.irtree = e_irtree_from_bundle(bundle),
|
||||
.bytecode = e_bytecode_from_bundle(bundle),
|
||||
};
|
||||
E_Interpretation interpretation = e_interpretation_from_bundle(bundle);
|
||||
eval.code = interpretation.code;
|
||||
eval.value = interpretation.value;
|
||||
eval.space = interpretation.space;
|
||||
return eval;
|
||||
}
|
||||
|
||||
internal E_Eval
|
||||
e_value_eval_from_eval(E_Eval eval)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
if(eval.irtree.mode == E_Mode_Offset)
|
||||
{
|
||||
E_TypeKey type_key = e_type_key_unwrap(eval.irtree.type_key, E_TypeUnwrapFlag_AllDecorative);
|
||||
E_TypeKind type_kind = e_type_kind_from_key(type_key);
|
||||
if(type_kind == E_TypeKind_Array)
|
||||
{
|
||||
eval.irtree.mode = E_Mode_Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
U64 type_byte_size = e_type_byte_size_from_key(type_key);
|
||||
Rng1U64 value_vaddr_range = r1u64(eval.value.u64, eval.value.u64 + type_byte_size);
|
||||
MemoryZeroStruct(&eval.value);
|
||||
if(!e_type_key_match(type_key, e_type_key_zero()) &&
|
||||
type_byte_size <= sizeof(E_Value) &&
|
||||
e_space_read(eval.space, &eval.value, value_vaddr_range))
|
||||
{
|
||||
eval.irtree.mode = E_Mode_Value;
|
||||
|
||||
// rjf: mask&shift, for bitfields
|
||||
if(type_kind == E_TypeKind_Bitfield && type_byte_size <= sizeof(U64))
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
E_Type *type = e_type_from_key__cached(type_key);
|
||||
U64 valid_bits_mask = 0;
|
||||
for(U64 idx = 0; idx < type->count; idx += 1)
|
||||
{
|
||||
valid_bits_mask |= (1ull<<idx);
|
||||
}
|
||||
eval.value.u64 = eval.value.u64 >> type->off;
|
||||
eval.value.u64 = eval.value.u64 & valid_bits_mask;
|
||||
eval.irtree.type_key = type->direct_type_key;
|
||||
scratch_end(scratch);
|
||||
}
|
||||
|
||||
// rjf: manually sign-extend
|
||||
switch(type_kind)
|
||||
{
|
||||
default: break;
|
||||
case E_TypeKind_Char8:
|
||||
case E_TypeKind_S8: {eval.value.s64 = (S64)*((S8 *)&eval.value.u64);}break;
|
||||
case E_TypeKind_Char16:
|
||||
case E_TypeKind_S16: {eval.value.s64 = (S64)*((S16 *)&eval.value.u64);}break;
|
||||
case E_TypeKind_Char32:
|
||||
case E_TypeKind_S32: {eval.value.s64 = (S64)*((S32 *)&eval.value.u64);}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ProfEnd();
|
||||
return eval;
|
||||
}
|
||||
|
||||
//- rjf: string-based helpers
|
||||
// TODO(rjf): (replace the old bundle APIs here)
|
||||
|
||||
//- rjf: type key -> auto hooks
|
||||
|
||||
internal E_ExprList
|
||||
e_auto_hook_exprs_from_type_key(Arena *arena, E_TypeKey type_key)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
E_ExprList exprs = {0};
|
||||
if(e_ir_ctx != 0)
|
||||
{
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
E_AutoHookMap *map = e_ir_ctx->auto_hook_map;
|
||||
String8 type_string = str8_skip_chop_whitespace(e_type_string_from_key(scratch.arena, type_key));
|
||||
|
||||
//- rjf: gather exact-type-key-matches from the map
|
||||
if(map != 0 && map->slots_count != 0)
|
||||
{
|
||||
U64 hash = e_hash_from_string(5381, type_string);
|
||||
U64 slot_idx = hash%map->slots_count;
|
||||
for(E_AutoHookNode *n = map->slots[slot_idx].first; n != 0; n = n->hash_next)
|
||||
{
|
||||
if(str8_match(n->type_string, type_string, 0))
|
||||
{
|
||||
e_expr_list_push(arena, &exprs, n->expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: gather fuzzy matches from all patterns in the map
|
||||
if(map != 0 && map->first_pattern != 0)
|
||||
{
|
||||
for(E_AutoHookNode *auto_hook_node = map->first_pattern;
|
||||
auto_hook_node != 0;
|
||||
auto_hook_node = auto_hook_node->pattern_order_next)
|
||||
{
|
||||
B32 fits_this_type_string = 1;
|
||||
U64 scan_pos = 0;
|
||||
for(String8Node *n = auto_hook_node->type_pattern_parts.first; n != 0; n = n->next)
|
||||
{
|
||||
if(n->string.size == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
U64 pattern_part_pos = str8_find_needle(type_string, scan_pos, n->string, 0);
|
||||
if(pattern_part_pos >= type_string.size)
|
||||
{
|
||||
fits_this_type_string = 0;
|
||||
break;
|
||||
}
|
||||
scan_pos = pattern_part_pos + n->string.size;
|
||||
}
|
||||
if(fits_this_type_string)
|
||||
{
|
||||
e_expr_list_push(arena, &exprs, auto_hook_node->expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
}
|
||||
ProfEnd();
|
||||
return exprs;
|
||||
}
|
||||
|
||||
internal E_ExprList
|
||||
e_auto_hook_exprs_from_type_key__cached(E_TypeKey type_key)
|
||||
{
|
||||
E_ExprList exprs = {0};
|
||||
{
|
||||
U64 hash = e_hash_from_string(5381, str8_struct(&type_key));
|
||||
U64 slot_idx = hash%e_cache->type_auto_hook_cache_map->slots_count;
|
||||
E_TypeAutoHookCacheNode *node = 0;
|
||||
for(E_TypeAutoHookCacheNode *n = e_cache->type_auto_hook_cache_map->slots[slot_idx].first;
|
||||
n != 0;
|
||||
n = n->next)
|
||||
{
|
||||
if(e_type_key_match(n->key, type_key))
|
||||
{
|
||||
node = n;
|
||||
}
|
||||
}
|
||||
if(node == 0)
|
||||
{
|
||||
node = push_array(e_cache->arena, E_TypeAutoHookCacheNode, 1);
|
||||
SLLQueuePush(e_cache->type_auto_hook_cache_map->slots[slot_idx].first, e_cache->type_auto_hook_cache_map->slots[slot_idx].last, node);
|
||||
node->key = type_key;
|
||||
node->exprs = e_auto_hook_exprs_from_type_key(e_cache->arena, type_key);
|
||||
}
|
||||
exprs = node->exprs;
|
||||
}
|
||||
return exprs;
|
||||
}
|
||||
|
||||
//- rjf: string IDs
|
||||
|
||||
internal U64
|
||||
e_id_from_string(String8 string)
|
||||
{
|
||||
U64 hash = e_hash_from_string(5381, string);
|
||||
U64 hash_slot_idx = hash%e_cache->string_id_map->hash_slots_count;
|
||||
E_StringIDNode *node = 0;
|
||||
for(E_StringIDNode *n = e_cache->string_id_map->hash_slots[hash_slot_idx].first; n != 0; n = n->hash_next)
|
||||
{
|
||||
if(str8_match(n->string, string, 0))
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(node == 0)
|
||||
{
|
||||
e_cache->string_id_gen += 1;
|
||||
U64 id = e_cache->string_id_gen;
|
||||
U64 id_slot_idx = id%e_cache->string_id_map->id_slots_count;
|
||||
node = push_array(e_cache->arena, E_StringIDNode, 1);
|
||||
SLLQueuePush_N(e_cache->string_id_map->hash_slots[hash_slot_idx].first, e_cache->string_id_map->hash_slots[hash_slot_idx].last, node, hash_next);
|
||||
SLLQueuePush_N(e_cache->string_id_map->id_slots[id_slot_idx].first, e_cache->string_id_map->hash_slots[id_slot_idx].last, node, id_next);
|
||||
node->id = id;
|
||||
node->string = push_str8_copy(e_cache->arena, string);
|
||||
}
|
||||
U64 result = node->id;
|
||||
return result;
|
||||
}
|
||||
|
||||
internal String8
|
||||
e_string_from_id(U64 id)
|
||||
{
|
||||
U64 id_slot_idx = id%e_cache->string_id_map->id_slots_count;
|
||||
E_StringIDNode *node = 0;
|
||||
for(E_StringIDNode *n = e_cache->string_id_map->id_slots[id_slot_idx].first; n != 0; n = n->id_next)
|
||||
{
|
||||
if(n->id == id)
|
||||
{
|
||||
node = n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
String8 result = {0};
|
||||
if(node != 0)
|
||||
{
|
||||
result = node->string;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Key Extension Functions
|
||||
|
||||
internal E_Key
|
||||
e_key_wrap(E_Key key, String8 string)
|
||||
{
|
||||
e_parent_key_push(key);
|
||||
E_Key result = e_key_from_string(string);
|
||||
e_parent_key_pop();
|
||||
return result;
|
||||
}
|
||||
|
||||
internal E_Key
|
||||
e_key_wrapf(E_Key key, char *fmt, ...)
|
||||
{
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
String8 string = push_str8fv(scratch.arena, fmt, args);
|
||||
E_Key result = e_key_wrap(key, string);
|
||||
va_end(args);
|
||||
scratch_end(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user