diff --git a/src/eval_visualization/eval_visualization_builtin_view_rules.c b/src/eval_visualization/eval_visualization_builtin_view_rules.c index 1f876e6a..7144bc0e 100644 --- a/src/eval_visualization/eval_visualization_builtin_view_rules.c +++ b/src/eval_visualization/eval_visualization_builtin_view_rules.c @@ -294,8 +294,8 @@ EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(default) for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next) { // rjf: unpack expansion info; skip out-of-bounds splits - U64 child_num = child->key.child_num; - U64 child_idx = child_num-1; + U64 child_id = child->key.child_id; + U64 child_idx = child_id-1; E_Expr *child_expr = ev_expr_from_block_index(arena, last_vb, child_idx); if(child_idx >= last_vb->semantic_idx_range.max) { @@ -369,8 +369,8 @@ EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(default) for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next) { // rjf: unpack expansion info; skip out-of-bounds splits - U64 child_num = child->key.child_num; - U64 child_idx = child_num-1; + U64 child_id = child->key.child_id; + U64 child_idx = child_id-1; E_Expr *child_expr = ev_expr_from_block_index(arena, last_vb, child_idx); if(child_idx >= last_vb->semantic_idx_range.max) { diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 67e8b879..5d84331a 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -40,12 +40,12 @@ EV_VIEW_RULE_EXPR_EXPAND_NUM_FROM_ID_FUNCTION_DEF(identity) //~ rjf: Key Functions internal EV_Key -ev_key_make(U64 parent_hash, U64 child_num) +ev_key_make(U64 parent_hash, U64 child_id) { EV_Key key; { key.parent_hash = parent_hash; - key.child_num = child_num; + key.child_id = child_id; } return key; } @@ -87,7 +87,7 @@ ev_hash_from_key(EV_Key key) { U64 data[] = { - key.child_num, + key.child_id, }; U64 hash = ev_hash_from_seed_string(key.parent_hash, str8((U8 *)data, sizeof(data))); return hash; @@ -253,7 +253,7 @@ ev_key_set_expansion(EV_View *view, EV_Key parent_key, EV_Key key, B32 expanded) EV_ExpandNode *prev = 0; for(EV_ExpandNode *n = parent_node->first; n != 0; n = n->next) { - if(n->key.child_num < key.child_num) + if(n->key.child_id < key.child_id) { prev = n; } @@ -621,23 +621,91 @@ ev2_block_tree_from_expr(Arena *arena, EV_View *view, String8 filter, String8 st } // rjf: iterate children expansions, recurse - // TODO(rjf): need to iterate these in index order, rather than "child_num" (which needs to be renamed to "child_id") order + // TODO(rjf): need to iterate these in index order, rather than "child_id" (which needs to be renamed to "child_id") order if(expand_info.row_count != 0 && expand_view_rule_info->expr_expand_range_info) { - for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next) + // rjf: count children + U64 child_count = 0; + for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next, child_count += 1){} + + // rjf: gather children keys & numbers + B32 needs_sort = 0; + EV_Key *child_keys = push_array(scratch.arena, EV_Key, child_count); + U64 *child_nums = push_array(scratch.arena, U64, child_count); { - U64 split_num = expand_view_rule_info->expr_expand_num_from_id(child->key.child_num, expand_info.user_data); + U64 idx = 0; + for(EV_ExpandNode *child = expand_node->first; child != 0; child = child->next, idx += 1) + { + child_keys[idx] = child->key; + child_nums[idx] = expand_view_rule_info->expr_expand_num_from_id(child->key.child_id, expand_info.user_data); + if(child_nums[idx] != child_keys[idx].child_id) + { + needs_sort = 1; + } + } + } + + // rjf: sort children by number, if needed + if(needs_sort) + { + for(U64 idx1 = 0; idx1 < child_count; idx1 += 1) + { + U64 min_idx2 = 0; + U64 min_num = child_nums[idx1]; + for(U64 idx2 = idx1+1; idx2 < child_count; idx2 += 1) + { + if(child_nums[idx2] < min_num) + { + min_idx2 = idx2; + min_num = child_nums[idx2]; + } + } + if(min_idx2 != 0) + { + Swap(EV_Key, child_keys[idx1], child_keys[min_idx2]); + Swap(U64, child_nums[idx1], child_nums[min_idx2]); + } + } + } + + // rjf: iterate children expansions & generate recursion tasks + for(U64 idx = 0; idx < child_count; idx += 1) + { + U64 split_num = child_nums[idx]; U64 split_relative_idx = split_num - 1; + if(split_relative_idx >= expand_info.row_count) + { + continue; + } EV_ExpandRangeInfo child_expand = expand_view_rule_info->expr_expand_range_info(arena, view, filter, t->expr, expand_params, r1u64(split_relative_idx, split_relative_idx+1), expand_info.user_data); if(child_expand.row_exprs_count > 0) { + EV_Key child_key = child_keys[idx]; + E_Expr *child_expr = child_expand.row_exprs[0]; EV_ViewRuleList *child_view_rules = ev_view_rule_list_from_inheritance(arena, t->view_rules); + String8 child_view_rule_string = ev_view_rule_from_key(view, child_key); + if(child_view_rule_string.size != 0) + { + ev_view_rule_list_push_string(arena, child_view_rules, child_view_rule_string); + } + else + { + Temp scratch = scratch_begin(&arena, 1); + E_IRTreeAndType child_irtree = e_irtree_and_type_from_expr(scratch.arena, child_expr); + String8 child_auto_view_rule_string = ev_auto_view_rule_from_type_key(child_irtree.type_key); + if(child_auto_view_rule_string.size != 0) + { + ev_view_rule_list_push_string(arena, child_view_rules, child_auto_view_rule_string); + } + scratch_end(scratch); + } + E_Expr *child_expr__resolved = ev_expr_from_expr_view_rules(arena, child_expr, child_view_rules); // TODO(rjf): need to mix in child's view rules Task *task = push_array(scratch.arena, Task, 1); SLLQueuePush(first_task, last_task, task); task->parent_block = expansion_block; - task->expr = child_expand.row_exprs[0]; - task->child_id = child->key.child_num; + task->expr = child_expr__resolved; + task->child_id = child_key.child_id; task->view_rules = child_view_rules; task->split_relative_idx = split_relative_idx; } @@ -843,7 +911,7 @@ ev2_num_from_key(EV2_BlockRangeList *block_ranges, EV_Key key) U64 hash = ev_hash_from_key(n->v.block->key); if(hash == key.parent_hash) { - U64 relative_num = n->v.block->expand_view_rule_info->expr_expand_num_from_id(key.child_num, n->v.block->expand_view_rule_info_user_data); + U64 relative_num = n->v.block->expand_view_rule_info->expr_expand_num_from_id(key.child_id, n->v.block->expand_view_rule_info_user_data); if(contains_1u64(n->v.range, relative_num-1)) { result = base_num + (relative_num - 1 - n->v.range.min); @@ -927,19 +995,38 @@ ev2_windowed_row_list_from_block_range_list(Arena *arena, EV_View *view, String8 { U64 child_num = block_relative_range.min + num_skipped + idx + 1; U64 child_id = n->v.block->expand_view_rule_info->expr_expand_id_from_num(child_num, n->v.block->expand_view_rule_info_user_data); + EV_Key row_key = ev_key_make(ev_hash_from_key(n->v.block->key), child_id); + E_Expr *row_expr = expand_range_info.row_exprs[idx]; + EV_ViewRuleList *row_view_rules = ev_view_rule_list_from_inheritance(arena, n->v.block->view_rules); + String8 row_view_rule_string = ev_view_rule_from_key(view, row_key); + if(row_view_rule_string.size != 0) + { + ev_view_rule_list_push_string(arena, row_view_rules, row_view_rule_string); + } + else + { + Temp scratch = scratch_begin(&arena, 1); + E_IRTreeAndType row_irtree = e_irtree_and_type_from_expr(scratch.arena, row_expr); + String8 row_auto_view_rule_string = ev_auto_view_rule_from_type_key(row_irtree.type_key); + if(row_auto_view_rule_string.size != 0) + { + ev_view_rule_list_push_string(arena, row_view_rules, row_auto_view_rule_string); + } + scratch_end(scratch); + } + E_Expr *row_expr__resolved = ev_expr_from_expr_view_rules(arena, row_expr, row_view_rules); EV2_Row *row = push_array(arena, EV2_Row, 1); SLLQueuePush(rows.first, rows.last, row); rows.count += 1; row->block = n->v.block; - row->key = ev_key_make(ev_hash_from_key(row->block->key), child_id); + row->key = row_key; row->visual_size = 1; row->visual_size_skipped = 0; // TODO(rjf) row->visual_size_chopped = 0; // TODO(rjf) row->string = n->v.block->string; - row->expr = expand_range_info.row_exprs[idx]; + row->expr = row_expr__resolved; row->member = expand_range_info.row_members[idx]; - row->view_rules = ev_view_rule_list_from_inheritance(arena, n->v.block->view_rules); - // TODO(rjf): mix in view rules based on row's key, row's type + row->view_rules = row_view_rules; } } } @@ -1182,8 +1269,8 @@ ev_block_list_from_view_expr_keys(Arena *arena, EV_View *view, String8 filter, E block->string = expr; block->expr = expr_resolved; block->view_rules = view_rule_list; - 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); + block->visual_idx_range = r1u64(key.child_id-1, key.child_id+0); + block->semantic_idx_range = r1u64(key.child_id-1, key.child_id+0); ev_block_end(&blocks, block); } @@ -1229,12 +1316,12 @@ ev_row_num_from_block_list_key(EV_BlockList *blocks, EV_Key key) { if(block->fzy_backing_items.v != 0) { - U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&block->fzy_backing_items, key.child_num); + U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&block->fzy_backing_items, key.child_id); this_block_contains_this_key = (item_num != 0 && contains_1u64(block->semantic_idx_range, item_num-1)); } else { - this_block_contains_this_key = (block->semantic_idx_range.min+1 <= key.child_num && key.child_num < block->semantic_idx_range.max+1); + this_block_contains_this_key = (block->semantic_idx_range.min+1 <= key.child_id && key.child_id < block->semantic_idx_range.max+1); } } if(this_block_contains_this_key) @@ -1242,12 +1329,12 @@ ev_row_num_from_block_list_key(EV_BlockList *blocks, EV_Key key) found = 1; if(block->fzy_backing_items.v != 0) { - U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&block->fzy_backing_items, key.child_num); + U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&block->fzy_backing_items, key.child_id); row_num += item_num-1-block->semantic_idx_range.min; } else { - row_num += key.child_num-1-block->semantic_idx_range.min; + row_num += key.child_id-1-block->semantic_idx_range.min; } break; } @@ -1281,12 +1368,12 @@ ev_key_from_block_list_row_num(EV_BlockList *blocks, S64 row_num) U64 item_idx = (U64)((row_num - vb_row_num_range.min) + vb->semantic_idx_range.min); if(item_idx < vb->fzy_backing_items.count) { - key.child_num = vb->fzy_backing_items.v[item_idx].idx; + key.child_id = vb->fzy_backing_items.v[item_idx].idx; } } else { - key.child_num = vb->semantic_idx_range.min + (row_num - vb_row_num_range.min) + 1; + key.child_id = vb->semantic_idx_range.min + (row_num - vb_row_num_range.min) + 1; } break; } @@ -1355,7 +1442,7 @@ ev_expr_from_block_index(Arena *arena, EV_Block *block, U64 index) FZY_Item *item = &block->fzy_backing_items.v[index]; EV_Key parent_key = block->parent_key; EV_Key key = block->key; - key.child_num = block->fzy_backing_items.v[index].idx; + key.child_id = block->fzy_backing_items.v[index].idx; // rjf: determine module to which this item belongs E_Module *module = e_parse_ctx->primary_module; diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 5588f3ae..8e2e2fac 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -11,7 +11,7 @@ typedef struct EV_Key EV_Key; struct EV_Key { U64 parent_hash; - U64 child_num; + U64 child_id; }; //////////////////////////////// @@ -461,7 +461,7 @@ global read_only EV2_Block ev2_nil_block = {&ev2_nil_block, &ev2_nil_block, &ev2 //////////////////////////////// //~ rjf: Key Functions -internal EV_Key ev_key_make(U64 parent_hash, U64 child_num); +internal EV_Key ev_key_make(U64 parent_hash, U64 child_id); internal EV_Key ev_key_zero(void); internal EV_Key ev_key_root(void); internal B32 ev_key_match(EV_Key a, EV_Key b); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index bb1c97e6..81bdb48f 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -5975,7 +5975,7 @@ rd_window_frame(RD_Window *ws) B32 row_is_expanded = ev_expansion_from_key(ev_view, row->key); if(row_is_expandable) UI_PrefWidth(ui_em(1.5f, 1)) - if(ui_pressed(ui_expanderf(row_is_expanded, "###%I64x_%I64x_is_expanded", row->key.parent_hash, row->key.child_num))) + if(ui_pressed(ui_expanderf(row_is_expanded, "###%I64x_%I64x_is_expanded", row->key.parent_hash, row->key.child_id))) { ev_key_set_expansion(ev_view, row->block->key, row->key, !row_is_expanded); } @@ -8506,12 +8506,20 @@ rd_ev_view_rule_expr_expand_range_info__debug_info_tables(Arena *arena, EV_View internal U64 rd_ev_view_rule_expr_id_from_num__debug_info_tables(U64 num, void *user_data, RDI_SectionKind section) { - return num; + RD_DebugInfoTableExpandAccel *accel = (RD_DebugInfoTableExpandAccel *)user_data; + U64 id = 0; + if(0 < num && num <= accel->items.count) + { + id = accel->items.v[num-1].idx+1; + } + return id; } internal U64 -rd_ev_view_rule_expr_num_from_id__debug_info_tables(U64 num, void *user_data, RDI_SectionKind section) +rd_ev_view_rule_expr_num_from_id__debug_info_tables(U64 id, void *user_data, RDI_SectionKind section) { + RD_DebugInfoTableExpandAccel *accel = (RD_DebugInfoTableExpandAccel *)user_data; + U64 num = fzy_item_num_from_array_element_idx__linear_search(&accel->items, id-1); return num; } @@ -8571,7 +8579,7 @@ rd_ev_view_rule_block_prod_collection_debug_tables(Arena *arena, RDI_SectionKind 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); + U64 item_num = fzy_item_num_from_array_element_idx__linear_search(&items, child->key.child_id); if(item_num != 0) { sub_expand_keys[idx] = child->key; @@ -8712,7 +8720,7 @@ rd_append_value_strings_from_eval(Arena *arena, EV_StringFlags flags, U32 defaul } //- rjf: member evaluations -> display member info - if(eval.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.type_key) && member != 0) + if(eval.mode == E_Mode_Null && !e_type_key_match(e_type_key_zero(), eval.type_key) && member != &e_member_nil) { U64 member_byte_size = e_type_byte_size_from_key(eval.type_key); String8 offset_string = str8_from_u64(arena, member->off, radix, 0, 0); diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 0c0748c2..e0c9c2cf 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -1291,7 +1291,7 @@ internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__meta_ctrl_en internal EV_ExpandInfo rd_ev_view_rule_expr_expand_info__debug_info_tables(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, RDI_SectionKind section); internal EV_ExpandRangeInfo rd_ev_view_rule_expr_expand_range_info__debug_info_tables(Arena *arena, EV_View *view, String8 filter, E_Expr *expr, MD_Node *params, Rng1U64 idx_range, void *user_data, RDI_SectionKind section); internal U64 rd_ev_view_rule_expr_id_from_num__debug_info_tables(U64 num, void *user_data, RDI_SectionKind section); -internal U64 rd_ev_view_rule_expr_num_from_id__debug_info_tables(U64 num, void *user_data, RDI_SectionKind section); +internal U64 rd_ev_view_rule_expr_num_from_id__debug_info_tables(U64 id, void *user_data, RDI_SectionKind section); internal void rd_ev_view_rule_block_prod_collection_debug_tables(Arena *arena, RDI_SectionKind target, EV_View *view, String8 filter, EV_Key parent_key, EV_Key key, EV_ExpandNode *expand_node, String8 string, E_Expr *expr, EV_ViewRuleList *view_rules, MD_Node *view_params, S32 depth, struct EV_BlockList *out); internal EV_View *rd_ev_view_from_key(U64 key); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index a001fb38..1c1cc2e5 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1749,8 +1749,8 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo // rjf: map selection keys to child numbers U64 selection_numbers[2] = { - selection_block->expand_view_rule_info->expr_expand_num_from_id(selection_keys_in_block[0].child_num, selection_block->expand_view_rule_info_user_data), - selection_block->expand_view_rule_info->expr_expand_num_from_id(selection_keys_in_block[1].child_num, selection_block->expand_view_rule_info_user_data), + selection_block->expand_view_rule_info->expr_expand_num_from_id(selection_keys_in_block[0].child_id, selection_block->expand_view_rule_info_user_data), + selection_block->expand_view_rule_info->expr_expand_num_from_id(selection_keys_in_block[1].child_id, selection_block->expand_view_rule_info_user_data), }; // rjf: determine collection info for the block @@ -1949,7 +1949,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo B32 next_row_expanded = row_expanded; RD_ViewRuleInfo *ui_view_rule_info = rd_view_rule_info_from_string(row->block->expand_view_rule_info->string); MD_Node *ui_view_rule_params_root = row->block->expand_view_rule_params; - if(ui_view_rule_info->ui == 0) + if(ui_view_rule_info->ui == 0 || !(ui_view_rule_info->flags & RD_ViewRuleInfoFlag_CanUseInWatchTable)) { ui_view_rule_info = &rd_nil_view_rule_info; ui_view_rule_params_root = &md_nil_node; @@ -2231,9 +2231,9 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo ////////////////////// //- rjf: draw start of cache lines in expansions // + U64 row_offset = row_eval.value.u64; if((row_eval.mode == E_Mode_Offset || row_eval.mode == E_Mode_Null) && - row_eval.value.u64%64 == 0 && row_depth > 0 && - !row_expanded) + row_offset%64 == 0 && row_depth > 0 && !row_expanded) { ui_set_next_fixed_x(0); ui_set_next_fixed_y(0); @@ -2585,9 +2585,9 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo //- rjf: [DEV] hovering -> watch key tooltips if(DEV_eval_watch_key_tooltips && ui_hovering(sig)) UI_Tooltip RD_Font(RD_FontSlot_Code) { - ui_labelf("Block Key: {0x%I64x, %I64u}", row->block->key.parent_hash, row->block->key.child_num); - ui_labelf("Row Key: {0x%I64x, %I64u}", row->key.parent_hash, row->key.child_num); - ui_labelf("Cursor Key: {0x%I64x, %I64u}", ewv->cursor.key.parent_hash, ewv->cursor.key.child_num); + ui_labelf("Block Key: {0x%I64x, %I64u}", row->block->key.parent_hash, row->block->key.child_id); + ui_labelf("Row Key: {0x%I64x, %I64u}", row->key.parent_hash, row->key.child_id); + ui_labelf("Cursor Key: {0x%I64x, %I64u}", ewv->cursor.key.parent_hash, ewv->cursor.key.child_id); ui_spacer(ui_em(1.f, 1.f)); ui_labelf("Cursor Table Coordinates: {%I64u, %I64u}", selection_tbl.min.x, selection_tbl.min.y); }