begin sketching out 'collections', which are the formal mechanism in the eval/eval-viz systems for visualizing synthetic structures/arrays/trees produced by the debugger, rather than ad-hocing / hardwiring the correct ev-block production for each kind of view - the views can still stay, but this is an important feature for other cases

This commit is contained in:
Ryan Fleury
2024-09-20 12:04:13 -07:00
parent bbd86449d8
commit 432e70caf6
10 changed files with 301 additions and 44 deletions
+1
View File
@@ -71,6 +71,7 @@ E_TypeKindTable:
{IncompleteEnum "enum" 0 }
{Bitfield "" 0 }
{Variadic "" 0 }
{Collection "" 0 }
}
@table(name op_kind precedence string op_pre op_sep op_pos)
+8 -4
View File
@@ -506,15 +506,18 @@ e_hash_from_type_key(E_TypeKey key)
str8_serial_push_struct(scratch.arena, &strings, &type->byte_size);
str8_serial_push_struct(scratch.arena, &strings, &type->count);
str8_serial_push_struct(scratch.arena, &strings, &type->off);
U64 direct_hash = e_hash_from_type_key(type->direct_type_key);
U64 owner_hash = e_hash_from_type_key(type->direct_type_key);
String8 direct_type_string = e_type_string_from_key(scratch.arena, type->direct_type_key);
String8 owner_type_string = e_type_string_from_key(scratch.arena, type->owner_type_key);
U64 direct_hash = e_hash_from_string(5381, direct_type_string);
U64 owner_hash = e_hash_from_string(5381, owner_type_string);
str8_serial_push_struct(scratch.arena, &strings, &direct_hash);
str8_serial_push_struct(scratch.arena, &strings, &owner_hash);
if(type->param_type_keys != 0)
{
for EachIndex(idx, type->count)
{
U64 param_type_hash = e_hash_from_type_key(type->param_type_keys[idx]);
String8 param_type_string = e_type_string_from_key(scratch.arena, type->param_type_keys[idx]);
U64 param_type_hash = e_hash_from_string(5381, param_type_string);
str8_serial_push_struct(scratch.arena, &strings, &param_type_hash);
}
}
@@ -522,7 +525,8 @@ e_hash_from_type_key(E_TypeKey key)
{
for EachIndex(idx, type->count)
{
U64 member_type_hash = e_hash_from_type_key(type->members[idx].type_key);
String8 member_type_string = e_type_string_from_key(scratch.arena, type->members[idx].type_key);
U64 member_type_hash = e_hash_from_string(5381, member_type_string);
str8_serial_push_struct(scratch.arena, &strings, &type->members[idx].off);
str8_serial_push_struct(scratch.arena, &strings, &member_type_hash);
}
+4 -2
View File
@@ -127,7 +127,7 @@ E_OpInfo e_expr_kind_op_info_table[45] =
{ E_OpKind_Binary, 13, str8_lit_comp(""), str8_lit_comp("="), str8_lit_comp("Define") },
};
U8 e_kind_basic_byte_size_table[55] =
U8 e_kind_basic_byte_size_table[56] =
{
0,
0,
@@ -184,9 +184,10 @@ U8 e_kind_basic_byte_size_table[55] =
0,
0,
0,
0,
};
String8 e_kind_basic_string_table[55] =
String8 e_kind_basic_string_table[56] =
{
str8_lit_comp(""),
str8_lit_comp("void"),
@@ -243,6 +244,7 @@ str8_lit_comp("class"),
str8_lit_comp("enum"),
str8_lit_comp(""),
str8_lit_comp(""),
str8_lit_comp(""),
};
C_LINKAGE_END
+3 -2
View File
@@ -74,6 +74,7 @@ E_TypeKind_IncompleteClass,
E_TypeKind_IncompleteEnum,
E_TypeKind_Bitfield,
E_TypeKind_Variadic,
E_TypeKind_Collection,
E_TypeKind_COUNT,
E_TypeKind_FirstBasic = E_TypeKind_Void,
E_TypeKind_LastBasic = E_TypeKind_ComplexF128,
@@ -159,8 +160,8 @@ extern String8 e_token_kind_strings[6];
extern String8 e_expr_kind_strings[45];
extern String8 e_interpretation_code_display_strings[11];
extern E_OpInfo e_expr_kind_op_info_table[45];
extern U8 e_kind_basic_byte_size_table[55];
extern String8 e_kind_basic_string_table[55];
extern U8 e_kind_basic_byte_size_table[56];
extern String8 e_kind_basic_string_table[56];
C_LINKAGE_END
@@ -165,7 +165,7 @@ EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(default)
}
// rjf: recurse for child
ev_append_expr_blocks__rec(arena, view, key, child->key, str8_zero(), child_expr, child_view_rules, depth, out);
ev_append_expr_blocks__rec(arena, view, filter, key, child->key, str8_zero(), child_expr, child_view_rules, depth, out);
}
ev_block_end(out, last_vb);
}
@@ -240,7 +240,7 @@ EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(default)
}
// rjf: recurse for child
ev_append_expr_blocks__rec(arena, view, key, child->key, str8_zero(), child_expr, child_view_rules, depth, out);
ev_append_expr_blocks__rec(arena, view, filter, key, child->key, str8_zero(), child_expr, child_view_rules, depth, out);
}
ev_block_end(out, last_vb);
}
@@ -272,7 +272,7 @@ EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(default)
}
// rjf: recurse for child
ev_append_expr_blocks__rec(arena, view, key, child_key, str8_zero(), child_expr, child_view_rules, depth, out);
ev_append_expr_blocks__rec(arena, view, filter, key, child_key, str8_zero(), child_expr, child_view_rules, depth, out);
}
scratch_end(scratch);
@@ -501,7 +501,6 @@ ev_block_begin(Arena *arena, EV_BlockKind kind, EV_Key parent_key, EV_Key key, S
n->v.key = key;
n->v.depth = depth;
n->v.expr = &e_expr_nil;
n->v.expr_raw = &e_expr_nil;
n->v.view_rules = &ev_nil_view_rule_list;
return &n->v;
}
@@ -515,7 +514,6 @@ ev_block_split_and_continue(Arena *arena, EV_BlockList *list, EV_Block *split_bl
EV_Block *continue_block = ev_block_begin(arena, split_block->kind, split_block->parent_key, split_block->key, split_block->depth);
continue_block->string = split_block->string;
continue_block->expr = split_block->expr;
continue_block->expr_raw = split_block->expr_raw;
continue_block->visual_idx_range = continue_block->semantic_idx_range = r1u64(split_idx+1, total_count);
continue_block->view_rules = split_block->view_rules;
continue_block->members = split_block->members;
@@ -536,7 +534,7 @@ ev_block_end(EV_BlockList *list, EV_Block *block)
}
internal void
ev_append_expr_blocks__rec(Arena *arena, EV_View *view, EV_Key parent_key, EV_Key key, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, S32 depth, EV_BlockList *list_out)
ev_append_expr_blocks__rec(Arena *arena, EV_View *view, String8 filter, EV_Key parent_key, EV_Key key, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, S32 depth, EV_BlockList *list_out)
{
ProfBeginFunction();
Temp scratch = scratch_begin(&arena, 1);
@@ -554,7 +552,6 @@ ev_append_expr_blocks__rec(Arena *arena, EV_View *view, EV_Key parent_key, EV_Ke
EV_Block *block = ev_block_begin(arena, EV_BlockKind_Root, parent_key, key, depth);
block->string = string;
block->expr = expr;
block->expr_raw = expr_raw;
block->view_rules = view_rules;
block->visual_idx_range = r1u64(key.child_num-1, key.child_num+0);
block->semantic_idx_range = r1u64(key.child_num-1, key.child_num+0);
@@ -581,7 +578,7 @@ ev_append_expr_blocks__rec(Arena *arena, EV_View *view, EV_Key parent_key, EV_Ke
//- rjf: do view rule children block generation, if we have an applicable view rule
if(parent_is_expanded && block_prod_view_rule_info != &ev_nil_view_rule_info)
{
block_prod_view_rule_info->block_prod(arena, view, parent_key, key, node, string, expr, view_rules, block_prod_view_rule_params, depth+1, list_out);
block_prod_view_rule_info->block_prod(arena, view, filter, parent_key, key, node, string, expr, view_rules, block_prod_view_rule_params, depth+1, list_out);
}
scratch_end(scratch);
@@ -589,7 +586,7 @@ ev_append_expr_blocks__rec(Arena *arena, EV_View *view, EV_Key parent_key, EV_Ke
}
internal EV_BlockList
ev_block_list_from_view_expr_keys(Arena *arena, EV_View *view, EV_ViewRuleList *view_rules, String8 expr, EV_Key parent_key, EV_Key key)
ev_block_list_from_view_expr_keys(Arena *arena, EV_View *view, String8 filter, EV_ViewRuleList *view_rules, String8 expr, EV_Key parent_key, EV_Key key, S32 depth)
{
ProfBeginFunction();
EV_BlockList blocks = {0};
@@ -641,7 +638,7 @@ ev_block_list_from_view_expr_keys(Arena *arena, EV_View *view, EV_ViewRuleList *
ev_view_rule_list_push_string(arena, view_rule_list, n->string);
}
ev_view_rule_list_push_string(arena, view_rule_list, view_rule_string);
ev_append_expr_blocks__rec(arena, view, parent_key, key, expr, parse.expr, view_rule_list, 0, &blocks);
ev_append_expr_blocks__rec(arena, view, filter, parent_key, key, expr, parse.expr, view_rule_list, depth, &blocks);
}
ProfEnd();
return blocks;
@@ -951,7 +948,6 @@ ev_row_list_push_new(Arena *arena, EV_View *view, EV_WindowedRowList *rows, EV_B
row->size_in_rows = 1;
row->string = block->string;
row->expr = expr_resolved;
row->expr_raw = expr;
if(row->expr->kind == E_ExprKind_MemberAccess)
{
Temp scratch = scratch_begin(&arena, 1);
@@ -1044,7 +1040,7 @@ ev_windowed_row_list_from_block_list(Arena *arena, EV_View *view, Rng1S64 visibl
case EV_BlockKind_Null:
case EV_BlockKind_Root:
{
ev_row_list_push_new(arena, view, &list, block, block->key, block->expr_raw);
ev_row_list_push_new(arena, view, &list, block, block->key, block->expr);
}break;
//////////////////////////////
@@ -1067,9 +1063,7 @@ ev_windowed_row_list_from_block_list(Arena *arena, EV_View *view, Rng1S64 visibl
for(U64 idx = visible_idx_range.min; idx < visible_idx_range.max; idx += 1)
{
FZY_Item *item = &block->fzy_backing_items.v[idx];
EV_Key parent_key = block->parent_key;
EV_Key key = block->key;
key.child_num = block->fzy_backing_items.v[idx].idx;
EV_Key key = ev_key_make(ev_hash_from_key(block->parent_key), block->fzy_backing_items.v[idx].idx);
E_Expr *row_expr = ev_expr_from_block_index(arena, block, idx);
ev_row_list_push_new(arena, view, &list, block, key, row_expr);
}break;
@@ -109,7 +109,7 @@ typedef enum EV_BlockKind
EV_BlockKind_EnumMembers, // members of enum
EV_BlockKind_Elements, // elements of array
EV_BlockKind_Canvas, // escape hatch for arbitrary UI
EV_BlockKind_DebugInfoTable, // block of filtered debug info table elements
EV_BlockKind_DebugInfoTable, // block of filtered debug info table elements
EV_BlockKind_COUNT,
}
EV_BlockKind;
@@ -126,7 +126,6 @@ struct EV_Block
// rjf: evaluation info
String8 string;
E_Expr *expr;
E_Expr *expr_raw;
// rjf: info about ranges that this block spans
Rng1U64 visual_idx_range;
@@ -173,7 +172,8 @@ struct EV_BlockArray
#define EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(name) ev_view_rule_expr_resolution__##name
#define EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_DEF(name) internal EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_SIG(EV_VIEW_RULE_EXPR_RESOLUTION_FUNCTION_NAME(name))
#define EV_VIEW_RULE_BLOCK_PROD_FUNCTION_SIG(name) void name(Arena *arena, \
EV_View *view, \
EV_View *view, \
String8 filter, \
EV_Key parent_key, \
EV_Key key, \
EV_ExpandNode *expand_node, \
@@ -285,7 +285,6 @@ struct EV_Row
String8 string;
E_Member *member;
E_Expr *expr;
E_Expr *expr_raw;
// rjf: view rule attachments
EV_ViewRuleList *view_rules;
@@ -374,8 +373,8 @@ internal E_Expr *ev_expr_from_expr_view_rules(Arena *arena, E_Expr *expr, EV_Vie
internal EV_Block *ev_block_begin(Arena *arena, EV_BlockKind kind, EV_Key parent_key, EV_Key key, S32 depth);
internal EV_Block *ev_block_split_and_continue(Arena *arena, EV_BlockList *list, EV_Block *split_block, U64 split_idx);
internal void ev_block_end(EV_BlockList *list, EV_Block *block);
internal void ev_append_expr_blocks__rec(Arena *arena, EV_View *view, EV_Key parent_key, EV_Key key, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, S32 depth, EV_BlockList *list_out);
internal EV_BlockList ev_block_list_from_view_expr_keys(Arena *arena, EV_View *view, EV_ViewRuleList *view_rules, String8 expr, EV_Key parent_key, EV_Key key);
internal void ev_append_expr_blocks__rec(Arena *arena, EV_View *view, String8 filter, EV_Key parent_key, EV_Key key, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, S32 depth, EV_BlockList *list_out);
internal EV_BlockList ev_block_list_from_view_expr_keys(Arena *arena, EV_View *view, String8 filter, EV_ViewRuleList *view_rules, String8 expr, EV_Key parent_key, EV_Key key, S32 depth);
internal void ev_block_list_concat__in_place(EV_BlockList *dst, EV_BlockList *to_push);
////////////////////////////////
+259 -6
View File
@@ -5804,7 +5804,7 @@ rd_window_frame(RD_Window *ws)
EV_View *ev_view = rd_ev_view_from_key(d_hash_from_string(ev_view_key_string));
EV_Key parent_key = ev_key_make(5381, 1);
EV_Key key = ev_key_make(ev_hash_from_key(parent_key), 1);
EV_BlockList viz_blocks = ev_block_list_from_view_expr_keys(scratch.arena, ev_view, &top_level_view_rules, expr, parent_key, key);
EV_BlockList viz_blocks = ev_block_list_from_view_expr_keys(scratch.arena, ev_view, str8_zero(), &top_level_view_rules, expr, parent_key, key, 0);
CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space);
U32 default_radix = (entity->kind == CTRL_EntityKind_Thread ? 16 : 10);
EV_WindowedRowList viz_rows = ev_windowed_row_list_from_block_list(scratch.arena, ev_view, r1s64(0, 50), &viz_blocks);
@@ -7851,6 +7851,213 @@ rd_window_frame(RD_Window *ws)
////////////////////////////////
//~ rjf: Eval Visualization
EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(rd_collection_block_prod)
{
//////////////////////////////
//- rjf: locals
//
if(str8_match(string, str8_lit("locals"), 0))
{
Temp scratch = scratch_begin(&arena, 1);
E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_parse_ctx->locals_map);
e_string2num_map_node_array_sort__in_place(&nodes);
EV_ViewRuleList top_level_view_rules = {0};
for(U64 idx = 0; idx < nodes.count; idx += 1)
{
E_String2NumMapNode *n = nodes.v[idx];
String8 root_expr_string = n->string;
FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, root_expr_string);
if(matches.count == matches.needle_part_count)
{
EV_Key local_parent_key = key;
EV_Key local_key = ev_key_make(ev_hash_from_key(local_parent_key), idx+1);
EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), &top_level_view_rules, root_expr_string, local_parent_key, local_key, depth);
ev_block_list_concat__in_place(out, &root_blocks);
}
}
scratch_end(scratch);
}
//////////////////////////////
//- rjf: registers
//
else if(str8_match(string, str8_lit("registers"), 0))
{
Temp scratch = scratch_begin(&arena, 1);
CTRL_Entity *thread = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->thread);
Arch arch = thread->arch;
U64 reg_count = regs_reg_code_count_from_arch(arch);
String8 *reg_strings = regs_reg_code_string_table_from_arch(arch);
U64 alias_count = regs_alias_code_count_from_arch(arch);
String8 *alias_strings = regs_alias_code_string_table_from_arch(arch);
U64 num = 1;
EV_ViewRuleList top_level_view_rules = {0};
ev_view_rule_list_push_string(arena, &top_level_view_rules, str8_lit("hex"));
for(U64 reg_idx = 1; reg_idx < reg_count; reg_idx += 1, num += 1)
{
String8 root_expr_string = push_str8f(arena, "reg:%S", reg_strings[reg_idx]);
FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, root_expr_string);
if(matches.count == matches.needle_part_count)
{
EV_Key reg_parent_key = key;
EV_Key reg_key = ev_key_make(ev_hash_from_key(reg_parent_key), num);
EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), &top_level_view_rules, root_expr_string, reg_parent_key, reg_key, depth);
ev_block_list_concat__in_place(out, &root_blocks);
}
}
for(U64 alias_idx = 1; alias_idx < alias_count; alias_idx += 1, num += 1)
{
String8 root_expr_string = push_str8f(arena, "reg:%S", alias_strings[alias_idx]);
FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, root_expr_string);
if(matches.count == matches.needle_part_count)
{
EV_Key reg_parent_key = ev_key_make(5381, 0);
EV_Key reg_key = ev_key_make(ev_hash_from_key(reg_parent_key), num);
EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), &top_level_view_rules, root_expr_string, reg_parent_key, reg_key, depth);
ev_block_list_concat__in_place(out, &root_blocks);
}
}
scratch_end(scratch);
}
//////////////////////////////
//- rjf: debug info tables
//
else if(str8_match(string, str8_lit("globals"), 0) ||
str8_match(string, str8_lit("thread_locals"), 0) ||
str8_match(string, str8_lit("types"), 0) ||
str8_match(string, str8_lit("procedures"), 0))
{
Temp scratch = scratch_begin(&arena, 1);
EV_ViewRuleList top_level_view_rules = {0};
RDI_SectionKind fzy_target = (str8_match(string, str8_lit("globals"), 0) ? RDI_SectionKind_GlobalVariables :
str8_match(string, str8_lit("thread_locals"), 0) ? RDI_SectionKind_ThreadVariables :
str8_match(string, str8_lit("types"), 0) ? RDI_SectionKind_UDTs :
str8_match(string, str8_lit("procedures"), 0) ? RDI_SectionKind_Procedures :
RDI_SectionKind_NULL);
if(fzy_target != RDI_SectionKind_NULL)
{
U64 endt_us = os_now_microseconds()+200;
//- rjf: unpack context
DI_KeyList dbgi_keys_list = d_push_active_dbgi_key_list(scratch.arena);
DI_KeyArray dbgi_keys = di_key_array_from_list(scratch.arena, &dbgi_keys_list);
U64 rdis_count = dbgi_keys.count;
RDI_Parsed **rdis = push_array(scratch.arena, RDI_Parsed *, rdis_count);
for(U64 idx = 0; idx < rdis_count; idx += 1)
{
rdis[idx] = di_rdi_from_key(rd_state->frame_di_scope, &dbgi_keys.v[idx], endt_us);
}
//- rjf: calculate top-level keys, expand root-level, grab root expansion node
EV_ExpandNode *root_node = ev_expand_node_from_key(view, key);
//- rjf: query all filtered items from dbgi searching system
U128 fuzzy_search_key = {rd_regs()->view.u64[0], rd_regs()->view.u64[1]};
B32 items_stale = 0;
FZY_Params params = {fzy_target, dbgi_keys};
FZY_ItemArray items = fzy_items_from_key_params_query(rd_state->frame_fzy_scope, fuzzy_search_key, &params, filter, endt_us, &items_stale);
if(items_stale)
{
rd_request_frame();
}
//- rjf: gather unsorted child expansion keys
//
// Nodes are sorted in the underlying expansion tree data structure, but
// ONLY by THEIR ORDER IN THE UNDERLYING DEBUG INFO TABLE. This is
// because debug info watch rows use the DEBUG INFO TABLE INDEX to form
// their key - this provides more stable/predictable behavior as rows
// are reordered, filtered, and shuffled around, as the user filters.
//
// When we actually build viz blocks, however, we want to produce viz
// blocks BY THE ORDER OF SUB-EXPANSIONS IN THE FILTERED ITEM ARRAY
// SPACE, so that all of the expansions come out in the right order.
//
EV_Key *sub_expand_keys = 0;
U64 *sub_expand_item_idxs = 0;
U64 sub_expand_keys_count = 0;
{
for(EV_ExpandNode *child = root_node->first; child != 0; child = child->next)
{
sub_expand_keys_count += 1;
}
sub_expand_keys = push_array(scratch.arena, EV_Key, sub_expand_keys_count);
sub_expand_item_idxs = push_array(scratch.arena, U64, sub_expand_keys_count);
U64 idx = 0;
for(EV_ExpandNode *child = root_node->first; child != 0; child = child->next)
{
U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&items, child->key.child_num);
if(item_num != 0)
{
sub_expand_keys[idx] = child->key;
sub_expand_item_idxs[idx] = item_num-1;
idx += 1;
}
else
{
sub_expand_keys_count -= 1;
}
}
}
//- rjf: sort child expansion keys
{
for(U64 idx1 = 0; idx1 < sub_expand_keys_count; idx1 += 1)
{
U64 min_idx2 = 0;
U64 min_item_idx = sub_expand_item_idxs[idx1];
for(U64 idx2 = idx1+1; idx2 < sub_expand_keys_count; idx2 += 1)
{
if(sub_expand_item_idxs[idx2] < min_item_idx)
{
min_idx2 = idx2;
min_item_idx = sub_expand_item_idxs[idx2];
}
}
if(min_idx2 != 0)
{
Swap(EV_Key, sub_expand_keys[idx1], sub_expand_keys[min_idx2]);
Swap(U64, sub_expand_item_idxs[idx1], sub_expand_item_idxs[min_idx2]);
}
}
}
//- rjf: build blocks for all table items, split by sorted sub-expansions
EV_Block *last_vb = ev_block_begin(arena, EV_BlockKind_DebugInfoTable, parent_key, key, depth);
{
last_vb->visual_idx_range = last_vb->semantic_idx_range = r1u64(0, items.count);
last_vb->fzy_target = fzy_target;
last_vb->fzy_backing_items = items;
}
for(U64 sub_expand_idx = 0; sub_expand_idx < sub_expand_keys_count; sub_expand_idx += 1)
{
FZY_Item *item = &items.v[sub_expand_item_idxs[sub_expand_idx]];
E_Expr *child_expr = ev_expr_from_block_index(arena, last_vb, sub_expand_item_idxs[sub_expand_idx]);
// rjf: form split: truncate & complete last block; begin next block
last_vb = ev_block_split_and_continue(arena, out, last_vb, sub_expand_item_idxs[sub_expand_idx]);
// rjf: build child view rules
EV_ViewRuleList *child_view_rules = ev_view_rule_list_from_inheritance(arena, &top_level_view_rules);
{
String8 view_rule_string = ev_view_rule_from_key(view, sub_expand_keys[sub_expand_idx]);
if(view_rule_string.size != 0)
{
ev_view_rule_list_push_string(arena, child_view_rules, view_rule_string);
}
}
// rjf: recurse for child
ev_append_expr_blocks__rec(arena, view, str8_zero(), key, sub_expand_keys[sub_expand_idx], str8_zero(), child_expr, child_view_rules, depth, out);
}
ev_block_end(out, last_vb);
}
scratch_end(scratch);
}
}
internal EV_View *
rd_ev_view_from_key(U64 key)
{
@@ -9929,7 +10136,6 @@ internal void
rd_frame(void)
{
Temp scratch = scratch_begin(0, 0);
DI_Scope *di_scope = di_scope_open();
local_persist S32 depth = 0;
log_scope_begin();
@@ -9950,6 +10156,11 @@ rd_frame(void)
rd_state->hover_regs = push_array(rd_frame_arena(), RD_Regs, 1);
rd_state->hover_regs_slot = RD_RegSlot_Null;
}
if(depth == 0)
{
rd_state->frame_di_scope = di_scope_open();
rd_state->frame_fzy_scope = fzy_scope_open();
}
//////////////////////////////
//- rjf: get events from the OS
@@ -10208,7 +10419,7 @@ rd_frame(void)
CTRL_Entity *m = n->v;
DI_Key dbgi_key = ctrl_dbgi_key_from_module(m);
eval_modules[eval_module_idx].arch = m->arch;
eval_modules[eval_module_idx].rdi = di_rdi_from_key(di_scope, &dbgi_key, 0);
eval_modules[eval_module_idx].rdi = di_rdi_from_key(rd_state->frame_di_scope, &dbgi_key, 0);
eval_modules[eval_module_idx].vaddr_range = m->vaddr_range;
eval_modules[eval_module_idx].space = rd_eval_space_from_ctrl_entity(ctrl_entity_ancestor_from_kind(m, CTRL_EntityKind_Process), RD_EvalSpaceKind_CtrlEntity);
if(module == m)
@@ -10227,7 +10438,7 @@ rd_frame(void)
for(CTRL_EntityNode *n = all_modules.first; n != 0; n = n->next, idx += 1)
{
DI_Key dbgi_key = ctrl_dbgi_key_from_module(n->v);
rdis[idx] = di_rdi_from_key(di_scope, &dbgi_key, 0);
rdis[idx] = di_rdi_from_key(rd_state->frame_di_scope, &dbgi_key, 0);
rdis_vaddr_ranges[idx] = n->v->vaddr_range;
if(n->v == module)
{
@@ -10274,13 +10485,35 @@ rd_frame(void)
////////////////////////////
//- rjf: build eval IR context
//
E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Collection, .name = str8_lit("collection"));
E_TypeKey meta_eval_type_key = e_type_key_cons_base(type(CTRL_MetaEval), str8_lit("entity"));
E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1);
{
E_TypeKey meta_eval_type_key = e_type_key_cons_base(type(CTRL_MetaEval), str8_lit("RADDBG_Entity"));
E_IRCtx *ctx = ir_ctx;
ctx->macro_map = push_array(scratch.arena, E_String2ExprMap, 1);
ctx->macro_map[0] = e_string2expr_map_make(scratch.arena, 512);
//- rjf: add macros for collections
{
String8 collection_names[] =
{
str8_lit_comp("locals"),
str8_lit_comp("registers"),
str8_lit_comp("globals"),
str8_lit_comp("thread_locals"),
str8_lit_comp("types"),
str8_lit_comp("procedures"),
};
for EachElement(idx, collection_names)
{
E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0);
expr->space = e_space_make(RD_EvalSpaceKind_MetaCollection);
expr->mode = E_Mode_Null;
expr->type_key = collection_type_key;
e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_names[idx], expr);
}
}
//- rjf: add macros for all evallable debugger frontend entities
{
RD_EntityKind evallable_kinds[] =
@@ -10379,6 +10612,17 @@ rd_frame(void)
EV_ViewRuleInfoTable *view_rule_info_table = push_array(scratch.arena, EV_ViewRuleInfoTable, 1);
{
ev_view_rule_info_table_push_builtins(scratch.arena, view_rule_info_table);
// rjf: collection view rule
{
EV_ViewRuleInfo info = {0};
info.string = str8_lit("collection");
info.flags = EV_ViewRuleInfoFlag_Expandable;
info.block_prod = EV_VIEW_RULE_BLOCK_PROD_FUNCTION_NAME(rd_collection_block_prod);
ev_view_rule_info_table_push(scratch.arena, view_rule_info_table, &info);
}
// rjf: raddbg-layer view rules
for EachEnumVal(RD_ViewRuleKind, k)
{
RD_ViewRuleInfo *src_info = &rd_view_rule_kind_info_table[k];
@@ -10400,6 +10644,7 @@ rd_frame(void)
EV_AutoViewRuleTable *auto_view_rule_table = push_array(scratch.arena, EV_AutoViewRuleTable, 1);
{
ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, e_type_key_cons_base(type(CTRL_MetaEvalFrameArray), str8_zero()), str8_lit("slice"));
ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, collection_type_key, str8_lit("collection"));
}
ev_select_auto_view_rule_table(auto_view_rule_table);
@@ -14752,6 +14997,14 @@ rd_frame(void)
}
}
di_scope_close(di_scope);
//////////////////////////////
//- rjf: close scopes
//
if(depth == 0)
{
di_scope_close(rd_state->frame_di_scope);
fzy_scope_close(rd_state->frame_fzy_scope);
}
scratch_end(scratch);
}
+4
View File
@@ -38,6 +38,7 @@ enum
RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined,
RD_EvalSpaceKind_MetaEntity,
RD_EvalSpaceKind_MetaCtrlEntity,
RD_EvalSpaceKind_MetaCollection,
};
////////////////////////////////
@@ -789,6 +790,8 @@ struct RD_State
// rjf: frame parameters
F32 frame_dt;
DI_Scope *frame_di_scope;
FZY_Scope *frame_fzy_scope;
// rjf: registers stack
RD_RegsNode base_regs;
@@ -1275,6 +1278,7 @@ internal void rd_window_frame(RD_Window *ws);
////////////////////////////////
//~ rjf: Eval Visualization
EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(rd_collection_block_prod);
internal EV_View *rd_ev_view_from_key(U64 key);
internal F32 rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, S32 depth, E_Eval eval, E_Member *member, EV_ViewRuleList *view_rules, String8List *out);
internal String8 rd_value_string_from_eval(Arena *arena, EV_StringFlags flags, U32 default_radix, FNT_Tag font, F32 font_size, F32 max_size, E_Eval eval, E_Member *member, EV_ViewRuleList *view_rules);
+8 -9
View File
@@ -1040,7 +1040,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, B32 modifiable, U32 default_radix, R
FuzzyMatchRangeList matches = fuzzy_match_find(scratch.arena, filter, expr_string);
if(matches.count == matches.needle_part_count)
{
EV_BlockList watch_blocks = ev_block_list_from_view_expr_keys(scratch.arena, eval_view, &top_level_view_rules, expr_string, parent_key, key);
EV_BlockList watch_blocks = ev_block_list_from_view_expr_keys(scratch.arena, eval_view, str8_zero(), &top_level_view_rules, expr_string, parent_key, key, 0);
ev_block_list_concat__in_place(&blocks, &watch_blocks);
}
}
@@ -1069,7 +1069,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, B32 modifiable, U32 default_radix, R
if(matches.count == matches.needle_part_count)
{
String8 expr_string = push_str8f(scratch.arena, "$%I64u", bp->id);
EV_BlockList watch_blocks = ev_block_list_from_view_expr_keys(scratch.arena, eval_view, &top_level_view_rules, expr_string, parent_key, key);
EV_BlockList watch_blocks = ev_block_list_from_view_expr_keys(scratch.arena, eval_view, str8_zero(), &top_level_view_rules, expr_string, parent_key, key, 0);
ev_block_list_concat__in_place(&blocks, &watch_blocks);
}
}
@@ -1096,7 +1096,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, B32 modifiable, U32 default_radix, R
if(matches.count == matches.needle_part_count)
{
String8 expr_string = push_str8f(scratch.arena, "$%I64u", wp->id);
EV_BlockList watch_blocks = ev_block_list_from_view_expr_keys(scratch.arena, eval_view, &top_level_view_rules, expr_string, parent_key, key);
EV_BlockList watch_blocks = ev_block_list_from_view_expr_keys(scratch.arena, eval_view, str8_zero(), &top_level_view_rules, expr_string, parent_key, key, 0);
ev_block_list_concat__in_place(&blocks, &watch_blocks);
}
}
@@ -1198,7 +1198,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, B32 modifiable, U32 default_radix, R
{
EV_Key parent_key = ev_key_make(5381, 0);
EV_Key key = ev_key_make(ev_hash_from_key(parent_key), num);
EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(scratch.arena, eval_view, &top_level_view_rules, root_expr_string, parent_key, key);
EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(scratch.arena, eval_view, str8_zero(), &top_level_view_rules, root_expr_string, parent_key, key, 0);
ev_block_list_concat__in_place(&blocks, &root_blocks);
}
}
@@ -1210,7 +1210,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, B32 modifiable, U32 default_radix, R
{
EV_Key parent_key = ev_key_make(5381, 0);
EV_Key key = ev_key_make(ev_hash_from_key(parent_key), num);
EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(scratch.arena, eval_view, &top_level_view_rules, root_expr_string, parent_key, key);
EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(scratch.arena, eval_view, str8_zero(), &top_level_view_rules, root_expr_string, parent_key, key, 0);
ev_block_list_concat__in_place(&blocks, &root_blocks);
}
}
@@ -1232,7 +1232,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, B32 modifiable, U32 default_radix, R
{
EV_Key parent_key = ev_key_make(5381, 0);
EV_Key key = ev_key_make(ev_hash_from_key(parent_key), idx+1);
EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(scratch.arena, eval_view, &top_level_view_rules, root_expr_string, parent_key, key);
EV_BlockList root_blocks = ev_block_list_from_view_expr_keys(scratch.arena, eval_view, str8_zero(), &top_level_view_rules, root_expr_string, parent_key, key, 0);
ev_block_list_concat__in_place(&blocks, &root_blocks);
}
}
@@ -1362,7 +1362,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, B32 modifiable, U32 default_radix, R
}
// rjf: recurse for child
ev_append_expr_blocks__rec(scratch.arena, eval_view, parent_key, sub_expand_keys[sub_expand_idx], str8_zero(), child_expr, child_view_rules, 0, &blocks);
ev_append_expr_blocks__rec(scratch.arena, eval_view, str8_zero(), parent_key, sub_expand_keys[sub_expand_idx], str8_zero(), child_expr, child_view_rules, 0, &blocks);
}
ev_block_end(&blocks, last_vb);
}break;
@@ -2511,8 +2511,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, B32 modifiable, U32 default_radix, R
cell_autocomp_flags = RD_AutoCompListerFlag_ViewRules;
if(cell_pre_edit_string.size == 0)
{
E_IRTreeAndType raw_irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr_raw);
cell_ghost_text = ev_auto_view_rule_from_type_key(raw_irtree.type_key);
cell_ghost_text = ev_auto_view_rule_from_type_key(row_eval.type_key);
}
}break;
case RD_WatchViewColumnKind_FrameSelection: