From 6f4533d8f52c5a84e89877da76234ff4476f988b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 2 Feb 2025 17:08:14 -0800 Subject: [PATCH] rd: new ctrl entity meta evaluation path; ctrl entity meta evaluation cache; eval: auto-view-rules (via 'auto hook map'), + support for 'type patterns', e.g. for templates; ir generation / typechecking hook application + source-tag coloring (to avoid infinite recursion of repeatedly-applied auto view rules --- src/eval/eval_ir.c | 177 +++++++++++++++++++++-- src/eval/eval_ir.h | 37 +++++ src/eval/eval_parse.c | 9 ++ src/eval/eval_parse.h | 16 +++ src/raddbg/raddbg_core.c | 295 ++++++++++++++++----------------------- src/raddbg/raddbg_core.h | 37 ++++- 6 files changed, 372 insertions(+), 199 deletions(-) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index ffb4f0a0..f83ea8a4 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -683,6 +683,99 @@ e_irgen_rule_from_string(String8 string) return rule; } +//////////////////////////////// +//~ 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, String8 pattern, String8 tag_expr_string) +{ + Temp scratch = scratch_begin(&arena, 1); + E_TokenArray tokens = e_token_array_from_text(scratch.arena, pattern); + E_Parse parse = e_parse_type_from_text_tokens(scratch.arena, pattern, &tokens); + E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, parse.expr); + E_TypeKey type_key = irtree.type_key; + E_AutoHookNode *node = push_array(arena, E_AutoHookNode, 1); + node->type_key = type_key; + U8 pattern_split = '?'; + node->type_pattern_parts = str8_split(arena, pattern, &pattern_split, 1, 0); + node->tag_expr = e_parse_expr_from_text(arena, push_str8_copy(arena, tag_expr_string)); + if(!e_type_key_match(e_type_key_zero(), type_key)) + { + U64 hash = e_hash_from_type_key(type_key); + U64 slot_idx = 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); + } + scratch_end(scratch); +} + +internal E_ExprList +e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key) +{ + E_ExprList exprs = {0}; + { + Temp scratch = scratch_begin(&arena, 1); + E_AutoHookMap *map = e_ir_ctx->auto_hook_map; + + //- rjf: gather exact-type-key-matches from the map + { + U64 hash = e_hash_from_type_key(type_key); + U64 slot_idx = hash%map->slots_count; + for(E_AutoHookNode *n = map->slots[slot_idx].first; n != 0; n = n->hash_next) + { + if(e_type_key_match(n->type_key, type_key)) + { + e_expr_list_push(arena, &exprs, n->tag_expr); + } + } + } + + //- rjf: gather fuzzy matches from all patterns in the map + if(map->first_pattern != 0) + { + String8 type_string = str8_skip_chop_whitespace(e_type_string_from_key(scratch.arena, type_key)); + 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) + { + 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(scan_pos < type_string.size) + { + fits_this_type_string = 0; + } + if(fits_this_type_string) + { + e_expr_list_push(arena, &exprs, auto_hook_node->tag_expr); + } + } + } + + scratch_end(scratch); + } + return exprs; +} + //////////////////////////////// //~ rjf: IR-ization Functions @@ -1767,9 +1860,12 @@ E_IRGEN_FUNCTION_DEF(default) internal E_IRTreeAndType e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { + Temp scratch = scratch_begin(&arena, 1); E_IRTreeAndType result = {&e_irnode_nil}; - E_IRGenRule *irgen_rule = &e_irgen_rule__default; - E_Expr *irgen_rule_tag = &e_expr_nil; + + //- rjf: pick the ir-generation rule from explicitly-stored expressions + E_IRGenRule *explicit_irgen_rule = &e_irgen_rule__default; + E_Expr *explicit_irgen_rule_tag = &e_expr_nil; for(E_Expr *tag = expr->first_tag; tag != &e_expr_nil; tag = tag->next) { String8 name = tag->first->string; @@ -1789,29 +1885,80 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) } if(!tag_is_poisoned) { - E_UsedTagNode *n = push_array(arena, E_UsedTagNode, 1); - n->tag = tag; - DLLPushBack(e_ir_ctx->used_tag_map->slots[slot_idx].first, e_ir_ctx->used_tag_map->slots[slot_idx].last, n); - irgen_rule_tag = tag; - irgen_rule = irgen_rule_candidate; + explicit_irgen_rule = irgen_rule_candidate; + explicit_irgen_rule_tag = tag; break; } } } - result = irgen_rule->irgen(arena, expr, irgen_rule_tag); - if(irgen_rule_tag != &e_expr_nil) + + //- rjf: apply all ir-generation steps + typedef struct Task Task; + struct Task { - U64 hash = e_hash_from_string(5381, str8_struct(&irgen_rule_tag)); - U64 slot_idx = hash%e_ir_ctx->used_tag_map->slots_count; - for(E_UsedTagNode *n = e_ir_ctx->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) + Task *next; + E_IRGenRule *rule; + E_Expr *tag; + }; + Task start_task = {0, explicit_irgen_rule, explicit_irgen_rule_tag}; + Task *first_task = &start_task; + Task *last_task = first_task; + for(Task *t = first_task; t != 0; t = t->next) + { + // rjf: poison the tag we are about to use, so we don't recursively use it + if(t->tag != &e_expr_nil) { - if(n->tag == irgen_rule_tag) + U64 hash = e_hash_from_string(5381, str8_struct(&t->tag)); + U64 slot_idx = hash%e_ir_ctx->used_tag_map->slots_count; + E_UsedTagNode *n = push_array(arena, E_UsedTagNode, 1); + n->tag = t->tag; + DLLPushBack(e_ir_ctx->used_tag_map->slots[slot_idx].first, e_ir_ctx->used_tag_map->slots[slot_idx].last, n); + } + + // rjf: do this rule's generation + result = t->rule->irgen(arena, expr, t->tag); + + // rjf: find any auto hooks according to this generation's type + { + E_ExprList exprs = e_auto_hook_tag_exprs_from_type_key(scratch.arena, result.type_key); + for(E_ExprNode *n = exprs.first; n != 0; n = n->next) { - DLLRemove(e_ir_ctx->used_tag_map->slots[slot_idx].first, e_ir_ctx->used_tag_map->slots[slot_idx].last, n); - break; + for(E_Expr *tag = n->v; tag != &e_expr_nil; tag = tag->next) + { + E_IRGenRule *rule = e_irgen_rule_from_string(tag->first->string); + if(rule == &e_irgen_rule__default) { rule = e_irgen_rule_from_string(tag->string); } + if(rule != &e_irgen_rule__default) + { + Task *task = push_array(scratch.arena, Task, 1); + SLLQueuePush(first_task, last_task, task); + task->rule = rule; + task->tag = tag; + break; + } + } } } } + + //- rjf: unpoison the tags we used + for(Task *t = first_task; t != 0; t = t->next) + { + if(t->tag != &e_expr_nil) + { + U64 hash = e_hash_from_string(5381, str8_struct(&t->tag)); + U64 slot_idx = hash%e_ir_ctx->used_tag_map->slots_count; + for(E_UsedTagNode *n = e_ir_ctx->used_tag_map->slots[slot_idx].first; n != 0; n = n->next) + { + if(n->tag == t->tag) + { + DLLRemove(e_ir_ctx->used_tag_map->slots[slot_idx].first, e_ir_ctx->used_tag_map->slots[slot_idx].last, n); + break; + } + } + } + } + + scratch_end(scratch); return result; } diff --git a/src/eval/eval_ir.h b/src/eval/eval_ir.h index b788412f..0e0a0710 100644 --- a/src/eval/eval_ir.h +++ b/src/eval/eval_ir.h @@ -172,6 +172,35 @@ struct E_IRGenRuleMap E_IRGenRuleSlot *slots; }; +//////////////////////////////// +//~ rjf: Type Pattern -> Hook Key Data Structure (Auto View Rules) + +typedef struct E_AutoHookNode E_AutoHookNode; +struct E_AutoHookNode +{ + E_AutoHookNode *hash_next; + E_AutoHookNode *pattern_order_next; + E_TypeKey type_key; + String8List type_pattern_parts; + E_Expr *tag_expr; +}; + +typedef struct E_AutoHookSlot E_AutoHookSlot; +struct E_AutoHookSlot +{ + E_AutoHookNode *first; + E_AutoHookNode *last; +}; + +typedef struct E_AutoHookMap E_AutoHookMap; +struct E_AutoHookMap +{ + U64 slots_count; + E_AutoHookSlot *slots; + E_AutoHookNode *first_pattern; + E_AutoHookNode *last_pattern; +}; + //////////////////////////////// //~ rjf: Used Tag Map Data Structure @@ -206,6 +235,7 @@ struct E_IRCtx E_String2ExprMap *macro_map; E_LookupRuleMap *lookup_rule_map; E_IRGenRuleMap *irgen_rule_map; + E_AutoHookMap *auto_hook_map; E_UsedTagMap *used_tag_map; }; @@ -259,6 +289,13 @@ internal void e_irgen_rule_map_insert(Arena *arena, E_IRGenRuleMap *map, E_IRGen internal E_IRGenRule *e_irgen_rule_from_string(String8 string); +//////////////////////////////// +//~ rjf: Auto Hooks + +internal E_AutoHookMap e_auto_hook_map_make(Arena *arena, U64 slots_count); +internal void e_auto_hook_map_insert_new(Arena *arena, E_AutoHookMap *map, String8 pattern, String8 tag_expr_string); +internal E_ExprList e_auto_hook_tag_exprs_from_type_key(Arena *arena, E_TypeKey type_key); + //////////////////////////////// //~ rjf: IR-ization Functions diff --git a/src/eval/eval_parse.c b/src/eval/eval_parse.c index e2265042..9185c159 100644 --- a/src/eval/eval_parse.c +++ b/src/eval/eval_parse.c @@ -823,6 +823,15 @@ e_expr_copy(Arena *arena, E_Expr *src) return result; } +internal void +e_expr_list_push(Arena *arena, E_ExprList *list, E_Expr *expr) +{ + E_ExprNode *n = push_array(arena, E_ExprNode, 1); + n->v = expr; + SLLQueuePush(list->first, list->last, n); + list->count +=1; +} + //////////////////////////////// //~ rjf: Expression Tree -> String Conversions diff --git a/src/eval/eval_parse.h b/src/eval/eval_parse.h index f4ee3afe..6104a1c4 100644 --- a/src/eval/eval_parse.h +++ b/src/eval/eval_parse.h @@ -67,6 +67,21 @@ struct E_Expr String8 bytecode; }; +typedef struct E_ExprNode E_ExprNode; +struct E_ExprNode +{ + E_ExprNode *next; + E_Expr *v; +}; + +typedef struct E_ExprList E_ExprList; +struct E_ExprList +{ + E_ExprNode *first; + E_ExprNode *last; + U64 count; +}; + //////////////////////////////// //~ rjf: Map Types @@ -229,6 +244,7 @@ internal E_Expr *e_expr_ref_deref(Arena *arena, E_Expr *rhs); internal E_Expr *e_expr_ref_cast(Arena *arena, E_TypeKey type_key, E_Expr *rhs); internal E_Expr *e_expr_ref_bswap(Arena *arena, E_Expr *rhs); internal E_Expr *e_expr_copy(Arena *arena, E_Expr *src); +internal void e_expr_list_push(Arena *arena, E_ExprList *list, E_Expr *expr); //////////////////////////////// //~ rjf: Expression Tree -> String Conversions diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index f8cb8411..6797e546 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2390,30 +2390,6 @@ rd_eval_space_from_cfg(RD_Cfg *cfg) return space; } -//- rjf: entity <-> eval space - -internal RD_Entity * -rd_entity_from_eval_space(E_Space space) -{ - RD_Entity *entity = &rd_nil_entity; - if(space.kind == RD_EvalSpaceKind_MetaEntity) - { - RD_Handle handle = {space.u64s[0], space.u64s[1]}; - entity = rd_entity_from_handle(handle); - } - return entity; -} - -internal E_Space -rd_eval_space_from_entity(RD_Entity *entity) -{ - E_Space space = e_space_make(RD_EvalSpaceKind_MetaEntity); - RD_Handle handle = rd_handle_from_entity(entity); - space.u64s[0] = handle.u64[0]; - space.u64s[1] = handle.u64[1]; - return space; -} - //- rjf: ctrl entity <-> eval space internal CTRL_Entity * @@ -2512,13 +2488,10 @@ rd_eval_blob_from_cfg__cached(RD_Cfg *cfg) { String8 result = {0}; { - // rjf: unpack RD_Cfg2EvalBlobMap *map = rd_state->cfg2evalblob_map; RD_Handle handle = rd_handle_from_cfg(cfg); U64 hash = d_hash_from_string(str8_struct(&handle)); U64 slot_idx = hash%map->slots_count; - - // rjf: cfg -> cached node RD_Cfg2EvalBlobNode *node = 0; for(RD_Cfg2EvalBlobNode *n = map->slots[slot_idx].first; n != 0; n = n->next) { @@ -2528,25 +2501,115 @@ rd_eval_blob_from_cfg__cached(RD_Cfg *cfg) break; } } - - // rjf: no node? -> try to build one if(node == 0) { - E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, cfg->string); - if(!e_type_key_match(e_type_key_zero(), type_key)) + node = push_array(rd_frame_arena(), RD_Cfg2EvalBlobNode, 1); + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, node); + node->handle = handle; + node->blob = rd_eval_blob_from_cfg(rd_frame_arena(), cfg); + } + result = node->blob; + } + return result; +} + +//- rjf: ctrl entity -> eval blob + +internal String8 +rd_eval_blob_from_entity(Arena *arena, CTRL_Entity *entity) +{ + String8 result = {0}; + String8 name = ctrl_entity_kind_code_name_table[entity->kind]; + E_TypeKey type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, name); + if(!e_type_key_match(e_type_key_zero(), type_key)) + { + Temp scratch = scratch_begin(&arena, 1); + MD_Node *schema = rd_schema_from_name(scratch.arena, name); + String8List fixed_width_parts = {0}; + String8List variable_width_parts = {0}; + { + E_Type *type = e_type_from_key(scratch.arena, type_key); + if(type->members != 0) for EachIndex(member_idx, type->count) { - node = push_array(rd_frame_arena(), RD_Cfg2EvalBlobNode, 1); - SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, node); - node->handle = handle; - node->blob = rd_eval_blob_from_cfg(rd_frame_arena(), cfg); + E_Member *member = &type->members[member_idx]; + String8 member_name = member->name; + if(0){} + else if(str8_match(member_name, str8_lit("frozen"), 0)) + { + str8_list_push(scratch.arena, &fixed_width_parts, str8((U8 *)&entity->is_frozen, 1)); + } + else if(str8_match(member_name, str8_lit("vaddr_range"), 0)) + { + str8_list_push(scratch.arena, &fixed_width_parts, str8_struct(&entity->vaddr_range)); + } + else if(str8_match(member_name, str8_lit("id"), 0)) + { + str8_list_push(scratch.arena, &fixed_width_parts, str8_struct(&entity->id)); + } + else if(str8_match(member_name, str8_lit("label"), 0)) + { + String8 label = entity->string; + if(entity->kind == CTRL_EntityKind_Module) + { + label = str8_skip_last_slash(label); + } + U64 off = type->byte_size + variable_width_parts.total_size; + str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8_struct(&off))); + str8_list_push(scratch.arena, &variable_width_parts, label); + str8_list_push(scratch.arena, &variable_width_parts, str8_lit("\0")); + } + else if(str8_match(member_name, str8_lit("exe"), 0)) + { + String8 string = entity->string; + U64 off = type->byte_size + variable_width_parts.total_size; + str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8_struct(&off))); + str8_list_push(scratch.arena, &variable_width_parts, string); + str8_list_push(scratch.arena, &variable_width_parts, str8_lit("\0")); + } + else if(str8_match(member_name, str8_lit("dbg"), 0)) + { + String8 string = ctrl_entity_child_from_kind(entity, CTRL_EntityKind_DebugInfoPath)->string; + U64 off = type->byte_size + variable_width_parts.total_size; + str8_list_push(scratch.arena, &fixed_width_parts, push_str8_copy(scratch.arena, str8_struct(&off))); + str8_list_push(scratch.arena, &variable_width_parts, string); + str8_list_push(scratch.arena, &variable_width_parts, str8_lit("\0")); + } } } - - // rjf: grab string from cached node - if(node != 0) + String8List all_parts = {0}; + str8_list_concat_in_place(&all_parts, &fixed_width_parts); + str8_list_concat_in_place(&all_parts, &variable_width_parts); + result = str8_list_join(arena, &all_parts, 0); + } + return result; +} + +internal String8 +rd_eval_blob_from_entity__cached(CTRL_Entity *entity) +{ + String8 result = {0}; + { + RD_Entity2EvalBlobMap *map = rd_state->entity2evalblob_map; + CTRL_Handle handle = entity->handle; + U64 hash = ctrl_hash_from_handle(handle); + U64 slot_idx = hash%map->slots_count; + RD_Entity2EvalBlobNode *node = 0; + for(RD_Entity2EvalBlobNode *n = map->slots[slot_idx].first; n != 0; n = n->next) { - result = node->blob; + if(ctrl_handle_match(n->handle, handle)) + { + node = n; + break; + } } + if(node == 0) + { + node = push_array(rd_frame_arena(), RD_Entity2EvalBlobNode, 1); + SLLQueuePush(map->slots[slot_idx].first, map->slots[slot_idx].last, node); + node->handle = handle; + node->blob = rd_eval_blob_from_entity(rd_frame_arena(), entity); + } + result = node->blob; } return result; } @@ -2743,70 +2806,17 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) } }break; - //- rjf: meta-control-enttiy reads (computed data about control entities) + //- rjf: meta-entity reads case RD_EvalSpaceKind_MetaCtrlEntity: { CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(space); - U64 hash = ctrl_hash_from_handle(entity->handle); - U64 slot_idx = hash%rd_state->ctrl_entity_meval_cache_slots_count; - RD_CtrlEntityMetaEvalCacheSlot *slot = &rd_state->ctrl_entity_meval_cache_slots[slot_idx]; - RD_CtrlEntityMetaEvalCacheNode *node = 0; - for(RD_CtrlEntityMetaEvalCacheNode *n = slot->first; n != 0; n = n->next) - { - if(ctrl_handle_match(n->handle, entity->handle)) - { - node = n; - break; - } - } - if(!node) - { - CTRL_MetaEval *meval = rd_ctrl_meta_eval_from_ctrl_entity(scratch.arena, entity); - String8 meval_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEval, meval); - U64 pos_min = arena_pos(rd_frame_arena()); - arena_push(rd_frame_arena(), 0, 64); - CTRL_MetaEval *meval_read = struct_from_serialized(rd_frame_arena(), CTRL_MetaEval, meval_srlzed); - struct_rebase_ptrs(CTRL_MetaEval, meval_read, meval_read); - U64 pos_opl = arena_pos(scratch.arena); - node = push_array(rd_frame_arena(), RD_CtrlEntityMetaEvalCacheNode, 1); - SLLQueuePush(slot->first, slot->last, node); - node->handle = entity->handle; - node->meval = meval_read; - node->range = r1u64(0, pos_opl-pos_min); - } - meval_read = node->meval; - meval_legal_range = node->range; - }goto meta_eval; - case RD_EvalSpaceKind_MetaEntity: - { - // rjf: calculate meta evaluation - CTRL_MetaEval *meval = rd_ctrl_meta_eval_from_entity(scratch.arena, rd_entity_from_eval_space(space)); - - // rjf: copy meta evaluation to scratch arena, to form range of legal reads - arena_push(scratch.arena, 0, 64); - String8 meval_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEval, meval); - U64 pos_min = arena_pos(scratch.arena); - meval_read = struct_from_serialized(scratch.arena, CTRL_MetaEval, meval_srlzed); - U64 pos_opl = arena_pos(scratch.arena); - - // rjf: rebase all pointer values in meta evaluation to be relative to base pointer - struct_rebase_ptrs(CTRL_MetaEval, meval_read, meval_read); - - // rjf: form legal range - meval_legal_range = r1u64(0, pos_opl-pos_min); - }goto meta_eval; - meta_eval:; - { - if(contains_1u64(meval_legal_range, range.min)) + String8 entity_eval_blob = rd_eval_blob_from_entity__cached(entity); + Rng1U64 legal_range = r1u64(0, entity_eval_blob.size); + Rng1U64 read_range = intersect_1u64(range, legal_range); + if(read_range.min < read_range.max) { result = 1; - U64 range_dim = dim_1u64(range); - U64 bytes_to_read = Min(range_dim, (meval_legal_range.max - range.min)); - MemoryCopy(out, ((U8 *)meval_read) + range.min, bytes_to_read); - if(bytes_to_read < range_dim) - { - MemoryZero((U8 *)out + bytes_to_read, range_dim - bytes_to_read); - } + MemoryCopy(out, entity_eval_blob.str + read_range.min, dim_1u64(read_range)); } }break; } @@ -2969,77 +2979,9 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) scratch_end(scratch); }break; - //- rjf: meta-entity writes - case RD_EvalSpaceKind_MetaEntity: - { - Temp scratch = scratch_begin(0, 0); - - // rjf: get entity, produce meta-eval - RD_Entity *entity = rd_entity_from_eval_space(space); - CTRL_MetaEval *meval = rd_ctrl_meta_eval_from_entity(scratch.arena, entity); - - // rjf: copy meta evaluation to scratch arena, to form range of legal reads - arena_push(scratch.arena, 0, 64); - String8 meval_srlzed = serialized_from_struct(scratch.arena, CTRL_MetaEval, meval); - U64 pos_min = arena_pos(scratch.arena); - CTRL_MetaEval *meval_read = struct_from_serialized(scratch.arena, CTRL_MetaEval, meval_srlzed); - U64 pos_opl = arena_pos(scratch.arena); - - // rjf: rebase all pointer values in meta evaluation to be relative to base pointer - struct_rebase_ptrs(CTRL_MetaEval, meval_read, meval_read); - - // rjf: perform write to entity - if(0){} -#define FlatMemberCase(name) else if(range.min == OffsetOf(CTRL_MetaEval, name) && dim_1u64(range) <= sizeof(meval_read->name)) -#define StringMemberCase(name) else if(range.min == (U64)meval_read->name.str) - FlatMemberCase(enabled) {result = 1; rd_entity_equip_disabled(entity, !!((U8 *)in)[0]);} - FlatMemberCase(debug_subprocesses) {result = 1; entity->debug_subprocesses = !!((U8 *)in)[0]; } - StringMemberCase(label) {result = 1; rd_entity_equip_name(entity, str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(exe) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Executable), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(args) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Arguments), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(working_directory) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_WorkingDirectory), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(entry_point) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_EntryPoint), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(stdout_path) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_StdoutPath), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(stderr_path) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_StderrPath), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(stdin_path) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_StdinPath), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(source_path) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Source), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(destination_path) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Dest), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(type) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Source), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(view_rule) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Dest), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(condition) {result = 1; rd_entity_equip_name(rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Condition), str8_cstring_capped(in, (U8 *)in + 4096));} - StringMemberCase(source_location) - { - result = 1; - String8TxtPtPair src_loc = str8_txt_pt_pair_from_string(str8_cstring_capped(in, (U8 *)in + 4096)); - RD_Entity *loc = rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Location); - rd_entity_equip_name(loc, src_loc.string); - rd_entity_equip_txt_pt(loc, src_loc.pt); - } - StringMemberCase(address_location) - { - U64 vaddr = 0; - if(try_u64_from_str8_c_rules(str8_cstring_capped(in, (U8 *)in + 4096), &vaddr)) - { - RD_Entity *loc = rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Location); - rd_entity_equip_vaddr(loc, vaddr); - rd_entity_equip_name(loc, str8_zero()); - loc->flags &= ~RD_EntityFlag_HasTextPoint; - result = 1; - } - } - StringMemberCase(function_location) - { - result = 1; - RD_Entity *loc = rd_entity_child_from_kind_or_alloc(entity, RD_EntityKind_Location); - loc->flags &= ~RD_EntityFlag_HasTextPoint; - rd_entity_equip_name(loc, str8_cstring_capped(in, (U8 *)in + 4096)); - } -#undef FlatMemberCase -#undef StringMemberCase - scratch_end(scratch); - }break; case RD_EvalSpaceKind_MetaCtrlEntity: { +#if 0 // TODO(rjf): @cfg Temp scratch = scratch_begin(0, 0); // rjf: get entity, produce meta-eval @@ -3064,6 +3006,7 @@ rd_eval_space_write(void *u, E_Space space, void *in, Rng1U64 range) #undef FlatMemberCase #undef StringMemberCase scratch_end(scratch); +#endif }break; } return result; @@ -9362,8 +9305,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul min_digits = (U32)num_value_eval.value.u64; } } - if(eval.space.kind == RD_EvalSpaceKind_MetaEntity || - eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + if(eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || eval.space.kind == RD_EvalSpaceKind_MetaCfg) { E_TypeKind kind = e_type_kind_from_key(eval.type_key); @@ -12161,6 +12103,9 @@ rd_frame(void) rd_state->cfg2evalblob_map = push_array(rd_frame_arena(), RD_Cfg2EvalBlobMap, 1); rd_state->cfg2evalblob_map->slots_count = 256; rd_state->cfg2evalblob_map->slots = push_array(rd_frame_arena(), RD_Cfg2EvalBlobSlot, rd_state->cfg2evalblob_map->slots_count); + rd_state->entity2evalblob_map = push_array(rd_frame_arena(), RD_Entity2EvalBlobMap, 1); + rd_state->entity2evalblob_map->slots_count = 256; + rd_state->entity2evalblob_map->slots = push_array(rd_frame_arena(), RD_Entity2EvalBlobSlot, rd_state->entity2evalblob_map->slots_count); ////////////////////////////// //- rjf: garbage collect untouched immediate cfg trees @@ -12863,6 +12808,8 @@ rd_frame(void) ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512); ctx->lookup_rule_map = push_array(scratch.arena, E_LookupRuleMap, 1); ctx->lookup_rule_map[0] = e_lookup_rule_map_make(scratch.arena, 512); + ctx->auto_hook_map = push_array(scratch.arena, E_AutoHookMap, 1); + ctx->auto_hook_map[0] = e_auto_hook_map_make(scratch.arena, 512); //- rjf: choose set of evallable meta names String8 evallable_meta_names[] = @@ -16302,17 +16249,9 @@ X(getting_started) { default:{is_static_for_ctrl_thread = 0;}break; case E_SpaceKind_Null: - case RD_EvalSpaceKind_MetaEntity: + case RD_EvalSpaceKind_MetaCfg: { is_static_for_ctrl_thread = 1; - RD_Entity *entity = rd_entity_from_eval_space(eval.space); - if(!rd_entity_is_nil(entity)) - { - MetaEvalNode *meval_node = push_array(scratch.arena, MetaEvalNode, 1); - meval_node->meval = rd_ctrl_meta_eval_from_entity(scratch.arena, entity); - SLLQueuePush(first_meval, last_meval, meval_node); - meval_count += 1; - } }break; } } diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 7dbc97af..b0ac9cba 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -95,7 +95,6 @@ enum { RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, RD_EvalSpaceKind_MetaCfg, - RD_EvalSpaceKind_MetaEntity, RD_EvalSpaceKind_MetaCtrlEntity, }; @@ -770,6 +769,31 @@ struct RD_Cfg2EvalBlobMap RD_Cfg2EvalBlobSlot *slots; }; +//////////////////////////////// +//~ rjf: Control Entity -> Eval Blob Cache Types + +typedef struct RD_Entity2EvalBlobNode RD_Entity2EvalBlobNode; +struct RD_Entity2EvalBlobNode +{ + RD_Entity2EvalBlobNode *next; + CTRL_Handle handle; + String8 blob; +}; + +typedef struct RD_Entity2EvalBlobSlot RD_Entity2EvalBlobSlot; +struct RD_Entity2EvalBlobSlot +{ + RD_Entity2EvalBlobNode *first; + RD_Entity2EvalBlobNode *last; +}; + +typedef struct RD_Entity2EvalBlobMap RD_Entity2EvalBlobMap; +struct RD_Entity2EvalBlobMap +{ + U64 slots_count; + RD_Entity2EvalBlobSlot *slots; +}; + //////////////////////////////// //~ rjf: Main Per-Process Graphical State @@ -842,8 +866,9 @@ struct RD_State // rjf: meta name -> eval type key map (constructed from-scratch each frame) E_String2TypeKeyMap *meta_name2type_map; - // rjf: config -> eval blob map (lazily constructed from-scratch each frame) + // rjf: eval blob caches (lazily constructed from-scratch each frame) RD_Cfg2EvalBlobMap *cfg2evalblob_map; + RD_Entity2EvalBlobMap *entity2evalblob_map; // rjf: registers stack RD_RegsNode base_regs; @@ -1215,10 +1240,6 @@ internal DR_FancyStringList rd_title_fstrs_from_ctrl_entity(Arena *arena, CTRL_E internal RD_Cfg *rd_cfg_from_eval_space(E_Space space); internal E_Space rd_eval_space_from_cfg(RD_Cfg *cfg); -//- rjf: entity <-> eval space -internal RD_Entity *rd_entity_from_eval_space(E_Space space); -internal E_Space rd_eval_space_from_entity(RD_Entity *entity); - //- rjf: ctrl entity <-> eval space internal CTRL_Entity *rd_ctrl_entity_from_eval_space(E_Space space); internal E_Space rd_eval_space_from_ctrl_entity(CTRL_Entity *entity, E_SpaceKind kind); @@ -1227,6 +1248,10 @@ internal E_Space rd_eval_space_from_ctrl_entity(CTRL_Entity *entity, E_SpaceKind internal String8 rd_eval_blob_from_cfg(Arena *arena, RD_Cfg *cfg); internal String8 rd_eval_blob_from_cfg__cached(RD_Cfg *cfg); +//- rjf: ctrl entity -> eval blob +internal String8 rd_eval_blob_from_entity(Arena *arena, CTRL_Entity *entity); +internal String8 rd_eval_blob_from_entity__cached(CTRL_Entity *entity); + //- rjf: entity -> meta eval internal CTRL_MetaEval *rd_ctrl_meta_eval_from_entity(Arena *arena, RD_Entity *entity); internal CTRL_MetaEval *rd_ctrl_meta_eval_from_ctrl_entity(Arena *arena, CTRL_Entity *entity);